欢迎来到天天文库
浏览记录
ID:9286836
大小:27.28 KB
页数:15页
时间:2018-04-26
《提高-java-代码性能的各种技巧》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、提高Java代码性能的各种技巧Java6,7,8中的String.intern–字符串池这篇文章将要讨论Java6中是如何实现 String.intern 方法的,以及这个方法在Java7以及Java8中做了哪些调整。字符串池字符串池(有名字符串标准化)是通过使用唯一的共享 String 对象来使用相同的值不同的地址表示字符串的过程。你可以使用自己定义的 Map (根据需要使用weak引用或者soft引用)并使用map中的值作为标准值来实现这个目标,或者你也可以使用JDK提供的 String.intern()。很多标准禁止在Jav
2、a6中使用 String.intern() 因为如果频繁使用池会市区控制,有很大的几率触发 OutOfMemoryException。OracleJava7对字符串池做了很多改进,你可以通过以下地址进行了解 http://bugs.sun.com/view_bug.do?bug_id=6962931以及 http://bugs.sun.com/view_bug.do?bug_id=6962930Java6中的String.intern()在美好的过去所有共享的String对象都存储在PermGen中—堆中固定大小的部分主要用于存储加载的类对象和字符串池。除了明
3、确的共享字符串,PermGen字符串池还包含所有程序中使用过的字符串(这里要注意是使用过的字符串,如果类或者方法从未加载或者被条用,在其中定义的任何常量都不会被加载)Java6中字符串池的最大问题是它的位置—PermGen。PermGen的大小是固定的并且在运行时是无法扩展的。你可以使用 -XX:MaxPermSize=N 配置来调整它的大小。据我了解,对于不同的平台默认的PermGen大小在32M到96M之间。你可以扩展它的大小,不过大小使用都是固定的。这个限制需要你在使用 String.intern 时需要非常小心—你最好不要使用这个方法intern任何无
4、法控制的用户输入。这是为什么在JAVA6中大部分使用手动管理 Map 来实现字符串池Java7中的String.intern()Java7中Oracle的工程师对字符串池的逻辑做了很大的改变—字符串池的位置被调整到heap中了。这意味着你再也不会被固定的内存空间限制了。所有的字符串都保存在堆(heap)中同其他普通对象一样,这使得你在调优应用时仅需要调整堆大小。这个改动使得我们有足够的理由让我们重新考虑在Java7中使用String.intern()。字符串池中的数据会被垃圾收集没错,在JVM字符串池中的所有字符串会被垃圾收集,如果这些值在应用中没有任何引用。
5、这是用于所有版本的Java,这意味着如果 interned的字符串在作用域外并且没有任何引用—它将会从JVM的字符串池中被垃圾收集掉。因为被重新定位到堆中以及会被垃圾收集,JVM的字符串池看上去是存放字符串的合适位置,是吗?理论上是—违背使用的字符串会从池中收集掉,当外部输入一个字符传且池中存在时可以节省内存。看起来是一个完美的节省内存的策略?在你回答这个之前,可以肯定的是你需要知道字符串池是如何实现的。在Java6,7,8中JVM字符串池的实现字符串池是使用一个拥有固定容量的 HashMap 每个元素包含具有相同hash值的字符串列表。一些实现的细节可以从J
6、avabug报告中获得 http://bugs.sun.com/view_bug.do?bug_id=6962930默认的池大小是1009(出现在上面提及的bug报告的源码中,在Java7u40中增加了)。在JAVA6早期版本中是一个常量,在随后的 java6u30至java6u41中调整为可配置的。而在java7中一开始就是可以配置的(至少在java7u02中是可以配置的)。你需要指定参数 -XX:StringTableSize=N, N是字符串池 Map 的大小。确保它是为性能调优而预先准备的大小。在Java6中这个参数没有太多帮助,因为你仍任被限制在固定
7、的PermGen内存大小中。后续的讨论将直接忽略Java6Java7(直至Java7u40)在Java7中,换句话说,你被限制在一个更大的堆内存中。这意味着你可以预先设置好String池的大小(这个值取决于你的应用程序需求)。通常说来,一旦程序开始内存消耗,内存都是成百兆的增长,在这种情况下,给一个拥有100万字符串对象的字符串池分配8-16M的内存看起来是比较适合的(不要使用1,000,000作为 -XX:StringTaleSize 的值–它不是质数;使用 1,000,003代替)你可能期待关于String在Map中的分配—可以阅读我之前关于HashCod
8、e方法调优的经验。你必须设置一个更大的
此文档下载收益归作者所有