现代 Java 应用程序有大量的字符串操做,例如,Web 服务 API 调用(JSON、REST、SOAP 等)、外部数据源调用(SQL、从 DB 返回的数据等)以及文本解析和文本建立等。所以,字符串对象很容易就占据了约至少 30% 的内存。然而,这些 String 对象中的大多数都是重复的,这些字符串的重复浪费了大量内存。所以,优化重复字符串对象浪费的内存是 Java 很是受欢迎的功能之一。在 G1 中,Java 就对此功能作了支持。算法
G1 GC 算法运行时,它将从内存中删除垃圾对象。它还从内存中删除重复的字符串对象(字符串重复数据删除)。能够经过设置如下 JVM 参数来激活此功能:编程
注意1:为了使用此功能, 须要在 Java 8 update 20 或更高版本上运行。工具
注意2:为了使用 -XX:+UseStringDeduplication ,您须要使用 G1 GC 算法。优化
选择这个简单的示例就是为了研究 JVM 如何处理重复的字符串,让咱们经过这个程序来验证 Java 的这个功能吧。3d
这个程序很是简单,主要就是建立字符串对象:cdn
1000 个“ Hello World-0”字符串实例对象
1000 个“ Hello World-1”字符串实例blog
1000 个“ Hello World-2”字符串实例内存
...字符串
...
...
1000 个“ Hello World-199”字符串实例
咱们使用两组不一样的 JVM 参数来运行这个程序。
第一次经过设置 -XX:+UseStringDeduplication JVM 参数来运行程序。即:
第二次,不设置 -XX:+UseStringDeduplication 参数的状况下运行同一程序:
在这两次运行中,咱们都捕获了堆的 Dump 信息,并经过堆的 Dump 分析工具 HeapHero.io 对其进行了分析。HeapHero.io 会检测因为各类无效的编程习惯而浪费的内存量,固然也包括因为重复的字符串而浪费的内存量。
从 HeapHero.io 的 Dump 分析报告中,咱们有一些有趣的发现:
即便在两次运行中都有相等数量的字符串对象(206K),因为运行第一组中重复的字符串而浪费的内存量为 5.6MB ,而在运行第二组中重复的字符串而浪费的内存量为 13.81MB 。
因为使用了 -XX:+UseStringDeduplication 参数,从应用程序中删除了大量重复字符串,从而大幅度减小内存消耗。所以,你能够利用 -XX:+UseG1GC-XX:+UseStringDeduplication 来减小重复字符串致使的内存浪费,它会减小应用程序的总体内存占用。