jvm编程理论
文章目录
在 Java 语言中,Sun 公司的工程师们对 String 对象做了大量的优化,来节约内存空间,提升 String 对象在系统中的性能。一起来看看优化过程,如下图所示:
工程师将 char[] 字段改为了 byte[] 字段,又维护了一个新的属性 coder,它是一个编码格式的标识。
工程师为什么这样修改呢?
我们知道一个 char 字符占 16 位,2 个字节。这个情况下,存储单字节编码内的字符(占一个字节的字符)就显得非常浪费。JDK1.9 的 String 类为了节约内存空间,于是使用了占 8 位,1 个字节的 byte 数组来存放字符串。
因此在Java9中,引入了一个叫做紧凑字符串(Compact String)的新特性,在String内部使用byte[]代替char[]。如果字符串的内容都是ISO-8859-1/Latin-1字符(1个字符1byte),则使用ISO-8859-1/Latin-1编码存储字符串,否则使用UTF-16编码存储数组(一个字符2byte或者4byte)。但是为了兼容,String类的方法向外表现的行为是与之前的版本一致的,比如toCharArray()和charAt()方法的行为依然和之前一致。
为了支持这一特性,Java引入了StringLatin1和StringUTF16两个新的辅助类用来提供静态方法供String类使用,举个例子,为了保证charAt()行为与之前版本的一致,Java9中的代码如下: ———————————————— 版权声明:本文为CSDN博主「I am zzxn」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_39438086/article/details/105424910
|
|
java8 不再共享char[] 的原因
-
“String.substring 方法也不再共享 char[],从而解决了使用该方法可能导致的内存泄漏问题。”
- 在Java6中substring方法会调用new string构造函数,此时会复用原来的char数组,而如果我们仅仅是用substring获取一小段字符,而原本string字符串非常大的情况下,substring的对象如果一直被引用,由于substring的里面的char数组仍然指向原字符串,此时string字符串也无法回收,从而导致内存泄露。
- 试想下,如果有大量这种通过substring获取超大字符串中一小段字符串的操作,会因为内存泄露而导致内存溢出。
文章作者 LYR
上次更新 2021-08-17