十大网站黄页的免费,中国建筑人才网怎么样,全屋设计装修效果图,wordpress界面菜单怎么弄String类可以说是Java编程中使用最多的类了#xff0c;如果能对String字符串的性能进行优化#xff0c;那么程序的性能必然能大幅提升。这不JDK9就对String字符串进行了改进升级#xff0c;在某些场景下可以让String字符串内存减少一半#xff0c;进而减少JVM的GC次数。Str… String类可以说是Java编程中使用最多的类了如果能对String字符串的性能进行优化那么程序的性能必然能大幅提升。这不JDK9就对String字符串进行了改进升级在某些场景下可以让String字符串内存减少一半进而减少JVM的GC次数。String的底层存储在面试的时候我们通常会说String字符串有不可变的特性每次都要创建新的字符串。那么为什么String字符串是不可变的呢先来看一下String字符串的底层存储结构public final class Stringimplements java.io.Serializable, ComparableString, CharSequence {private final char value[];public String() {this.value .value;}public String(String original) {this.value original.value;this.hash original.hash;}// ...
}
看到什么了当我们new一个String对象时对应的字符串其实是以char数组的形式存储在String对象内部。而这个char数组是final的也就是说不可变的。这也就是为什么我们说String字符串拥有不可变的特性当字符串改变了char数组不可变就只能创建一个新的对象新的char数组了。底层存储的优化上面说的情况是JDK8及以前版本到了JDK9String中字符串的存储不再用char数组了改用byte数组。public final class Stringimplements java.io.Serializable, ComparableString, CharSequence {Stableprivate final byte[] value;private final byte coder;Native static final byte LATIN1 0;Native static final byte UTF16 1;static final boolean COMPACT_STRINGS;public String() {this.value .value;this.coder .coder;}HotSpotIntrinsicCandidatepublic String(String original) {this.value original.value;this.coder original.coder;this.hash original.hash;}// ...
}
不仅将char数组改为byte数组而且新增了一个coder的成员变量。在程序中绝大多数字符串只包含英文字母数字等字符使用Latin-1编码一个字符占用一个byte。如果使用char一个char要占用两个byte会占用双倍的内存空间。但是如果字符串中使用了中文等超出Latin-1表示范围的字符使用Latin-1就没办法表示了。这时JDK会使用UTF-16编码那么占用的空间和旧版使用char[]是一样的。coder变量代表编码的格式目前String支持两种编码格式Latin-1和UTF-16。Latin-1需要用一个字节来存储而UTF-16需要使用2个字节或者4个字节来存储。据说这一改进方案是JDK的开发人员用大数据和人工能智能调研了成千上万的应用程序的heapdump信息后得出大部分的String都是以Latin-1字符编码来表示的只需要一个字节存储就够了两个字节完全是浪费。COMPACT_STRINGS属性则是用来控制是否开启String的compact功能。默认情况下是开启的。可以使用-XX:-CompactStrings参数来对此功能进行关闭。改进的好处改进的好处是非常明显的首先如果项目中使用Latin-1字符集居多内存的占用大幅度减少同样的硬件配置可以支撑更多的业务。当内存减少之后进一步导致减少GC次数进而减少Stop-The-World的频次同样会提升系统的性能。总结随着JDK的迭代String字符串的内存结构及方法等也在不断的发展演变一方面是精于求精的态度另一个更重要的原因是String在代码中很常见并且它往往是JVM中占用内存最多的一类数据因此对它(String)的优化收益非常大。