String的缓存机制是什么样的?(3)

上一期中我们介绍了intern()方法的定义和它在不同JDK版本中的实现。String 的intern()方法能将我们创建的字符串维护到缓存池中,当需要使用的时候就会从缓存池中获取。

听起来很不错是吧?但实际使用起来不是那么美好。

在上期我们提到:jdk6和jdk7中缓存池在JVM中的位置是不一样的。在jdk6中,缓存池是存放在方法区的“永久代”中的,而在jdk7以后,缓存池被放置在了堆内存中。

而方法区中的“永久代”空间是有限的,而且也基本不会被FullGC之外的垃圾收集器照顾到。如果intern()方法在jdk中被大量使用,那缓存池很快就会被占满,从而引发OOM异常。因此在jdk6中,不推荐大量使用intern()方法。

在jdk7后,缓存池被放置到了堆内存中,这样就极大地避免了缓存池被占满的情况。但是一旦缓存池中的字符串达到一定规模后,性能就会急剧下降,因此默认的缓存池大小也在不断的扩大中,从最初的1009到7u40的60013,。我们可以使用如下两个参数打印和修改缓存池的大小。

-XX:+PrintStringTableStatistics

-XX:StringTableSize=N

Intern()方法是一种显示的排重机制,何为显示的?即需要开发者写代码时明确调用。这样就会带来两个问题:

1、使用不方便,每次写代码时都要记得去调用。

2、很难保证缓存池的效率,因此缓存池有大小限制,在代码中大量调用的话可能反而会影响整个系统的性能。

当然jdk官方也注意到了这个问题,因此在Oracle JDK 8u20后推出了一个新特性,即G1 GC下的字符串排重。这个特性是针对JVM底层进行了修改,java类型并不需要做任何改动。

不过这个功能目前是默认关闭的,需要在指定使用G1 GC的前提下,使用如下参数打开:

-XX:+UseStringDeduplication

至此,String的缓存机制我们就全部介绍完了,相信经过大家的思考,能进一步地理解String的缓存机制。

展开阅读全文

页面更新:2024-04-18

标签:缓存   机制   字符串   大小   内存   性能   参数   两个   代码   方法

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top