Eureka 源码解析 —— StringCache
来源:互联网 发布:艾默生ups监控软件 编辑:程序博客网 时间:2024/06/02 03:46
摘要: 原创出处 http://www.iocoder.cn/Eureka/string-cache/ 「芋道源码」欢迎转载,保留摘要,谢谢!
- 1. 概述
- 2. StringCache
- 3. 使用场景
- 666. 彩蛋
1. 概述
本文主要分享 Eureka 自己实现的 StringCache。
先一起来看下美团点评技术团队对 String#intern(...)
的分享:
FROM 《深入解析String#intern》「 引言 」
在 JAVA 语言中有8中基本类型和一种比较特殊的类型String
。这些类型为了使他们在运行过程中速度更快,更节省内存,都提供了一种常量池的概念。常量池就类似一个 JAVA 系统级别提供的缓存。
8 种基本类型的常量池都是系统协调的,String
类型的常量池比较特殊。它的主要使用方法有两种:
- 直接使用双引号声明出来的
String
对象会直接存储在常量池中- 如果不是用双引号声明的
String
对象,可以使用String提供的intern
方法。intern
方法会从字符串常量池中查询当前字符串是否存在,若不存在就会将当前字符串放入常量池中
- 字符串常量池能带来速度更快,更节省内存的好处
- 非双引号声明的 String 对象,需要使用
String#intern()
方法,将字符串存储到字符串常量池。
看起来一切都非常非常非常美好,那为什么 Eureka 自己实现了 StringCache ?
继续参见美团点评技术团队对 String#intern(...)
的分享:
FROM 《深入解析String#intern》「 native 代码 」
JAVA 使用 JNI 调用 c++ 实现的 StringTable 的intern
方法, StringTable的intern
方法跟 Java 中的 HashMap 的实现是差不多的, 只是不能自动扩容。默认大小是1009。要注意的是,String 的 String Pool 是一个固定大小的 Hashtable,默认值大小长度是 1009,如果放进 String Pool 的 String 非常多,就会造成Hash冲突严重,从而导致链表会很长,而链表长了后直接会造成的影响就是当调用String.intern时性能会大幅下降(因为要一个一个找)。
在 JDK6 中 StringTable 是固定的,就是 1009 的长度,所以如果常量池中的字符串过多就会导致效率下降很快。在jdk7中,StringTable的长度可以通过一个参数指定:
- -XX:StringTableSize=99991
- JDK 自带的 String Pool 固定大小( 即使可配 ),不支持自动扩容,大量使用
String#intern(...)
后,会导致性能大幅度下降。 - Eureka 的应用实例( InstanceInfo ) 的
appName
、appGroupName
、vipAddress
、secureVipAddress
、metadata
和应用( Application )的name
等属性需要使用到 String Pool ,为了在大量的网络通信序列化反序列的过程中,速度更快,更节省内容。
另外,FastJSON 在 1.124 版本之前也使用 String#intern(...)
方法,优化 JSON Key 的速度和空间,但是在大量动态 JSON Key 的场景下,反而会导致性能下降。所以 FastJSON 1.124 修复了该问题。参见如下:
FROM 《深入解析String#intern》「 fastjson 不当使用 」
- But ,FastJSON 1.124 版本之前恰好适合 Eureka ,因为
appName
、appGroupName
相对不那么动态。考虑到可能还是有大量的字符串存在,因而实现自定义的 StringCache 类,以解决 StringPool 的 HashTable 不支持动态扩容的情况。
OK,下面我们来看看 Eureka 是如何实现自定义的 StringCache 类。
推荐 Spring Cloud 书籍:
- 请支持正版。下载盗版,等于主动编写低级 BUG 。
- 程序猿DD —— 《Spring Cloud微服务实战》
- 周立 —— 《Spring Cloud与Docker微服务架构实战》
- 两书齐买,京东包邮。
2. StringCache
com.netflix.discovery.util.StringCache
,字符串缓存。代码如下:
INSTANCE
属性,字符串缓存单例。lock
属性,读写锁,保证读写互斥。cache
属性,缓存哈希表。- 使用 WeakHashMap,当 StringCache 被回收时,其对应的值一起被移除。
- 《WeakHashMap和HashMap的区别》
- 《Java 集合系列13之 WeakHashMap详细介绍(源码解析)和使用示例》
lengthLimit
属性,缓存字符串最大长度。默认值:38 。#cachedValueOf(...)
方法,获得字符串缓存。若缓存不存在,则进行缓存。和String#intern()
的逻辑相同,区别在于cache
支持自动扩容。- 第 22 至 30 行 :读锁,读取缓存。
- 第 32 至 42 行 :缓存不存在,写锁,写入缓存。
#size()
方法,缓存大小。#intern()
静态方法,使用INSTANCE
获取缓存字符串。
3. 使用场景
在 InstanceInfo 下的使用,点击 链接 查看。
在 Application 下的使用,点击 链接 查看。
- Eureka 源码解析 —— StringCache
- Eureka 源码解析 —— Eureka-Server 集群同步
- Eureka 源码解析 —— 任务批处理
- Eureka 源码解析 —— 网络通信
- Eureka 源码解析 —— EndPoint 与 解析器
- Eureka 源码解析 —— Eureka-Client 初始化(一)之 EurekaInstanceConfig
- Eureka 源码解析 —— Eureka-Client 初始化(二)之 EurekaClientConfig
- Eureka 源码解析 —— Eureka-Client 初始化(三)之 EurekaClient
- Eureka 源码解析 —— Eureka-Server 启动(一)之 ServerConfig
- Eureka 源码解析 —— Eureka-Server 启动(二)之 EurekaBootStrap
- Eureka 源码解析 —— 项目结构简介
- Eureka 源码解析 —— 调试环境搭建
- Eureka 源码解析 —— 注册表 InstanceRegistry 类关系
- eureka客户端源码解析
- Eureka 源码解析 —— Eureka源码解析 —— 应用实例注册发现 (九)之岁月是把萌萌的读写锁
- Eureka 源码解析 —— 应用实例注册发现(一)之注册
- Eureka 源码解析 —— 应用实例注册发现(二)之续租
- Eureka 源码解析 —— 应用实例注册发现(三)之下线
- OpenCV Mat结构的图片 旋转顺时针90度 180度 270度 逆时针90度
- zookeeper单机模式的搭建
- spring boot 之热部署
- GlusterFS安装及集群规划
- error: “Font”: 不明确的符号
- Eureka 源码解析 —— StringCache
- 合并两个有序列表的循环和递归实现
- echarts多列柱状图求合计,并且展示在最顶端
- win redis 安装 基本操作 设置密码
- git版本控制初始
- try exception 捕获异常
- 各种语言一句话反弹shell
- Python3网络爬虫(二):利用urllib.urlopen向有道翻译发送数据获得翻译结果
- Linxu环境下ZooKeeper的集群搭建之详细教程