jdk9为何要将String的底层实现由char[]改成了byte[]

先说结论:出于节省String占用jvm的内存空间。

优化String节省jvm内存空间的必要性

(1)调查统计发现一个java系统,堆里面存活最多的对象之一就是String对象,所以优化String的占用空间是很有意义的,因为String是实际开发中使用最频繁的类。否则,你去优化一个平时根本不怎么用到的类,那么就很鸡肋了。
在这里插入图片描述

上图是基于java8运行的spring boot系统对象数量的快照,我们可以看到String对象有82039个,占用了1968936字节的内存,占用内存排在第5位。

这里注意的是java8中String内部实现是char[],我们可以看到内存占用排在第2位的就是char[]。

char[]对象有89140个,内存占用了11354176字节,从个数数量级上来看,你会发现char[]对象其实大部分来源于String对象内部维护的那个char[]。

(2)调查统计还发现了一个事实,就是开发者使用到的文本字符串中的字符,大部分使用一个字节来表示就足够了。

String a = ?;

上面的字符串,大家平时都填的什么?

作为来自中国的开发者,开发经历中大部分填的都是英文字母和数字,也很少往上面填自己的母语中文。而这些字符,普遍使用一个字节就能表示了。

如何优化空间的

(1)char类型的数据在jvm中占用了两个字节的空间,使用的是UTF-16编码。

jvm规范中是如下描述的:

char, whose values are 16-bit unsigned integers representing Unicode
code points in the Basic Multilingual Plane, encoded with UTF-16, and
whose default value is the null code point (’\u0000’)。

所以使用char[]来表示String就导致了即使String中的字符单个字节就能表示,还是得占用了两个字节,而实际开发中使用频率最高的却是单字节的字符。

(2)优化为byte[],并提供了另外一种编码可能性。

仅仅优化为byte[]是不够的,关键是提供了ISO-8859-1/Latin-1编码可能(Latin-1就是ISO-8859-1)。

Latin-1编码是用单个字节来表示字符,比两个字节的utf-16节省了一半空间。
所以String类中多了一个编码标志位coder,用来表示使用的是utf-16编码,还是Latin-1编码。

/**
 * The identifier of the encoding used to encode the bytes in
 * {@code value}. The supported values in this implementation are
 *
 * LATIN1
 * UTF16
 *
 * @implNote This field is trusted by the VM, and is a subject to
 * constant folding if String instance is constant. Overwriting this
 * field after construction will cause problems.
 */
private final byte coder;

java会根据字符串的内容自动设置相应的编码,要么UTF16,要么LATIN1。

对于这种:

String name="jack";

使用LATIN1编码,占用4个字节就够了,而原来的char[],就得占用8个字节。

对于这种:

String name="小明";

没得办法,和char[]表示String没什么区别,即使现在是byte[]来表示String,还是得乖乖用UTF16编码,和优化之前一样,没节省空间(LATIN1编码集支持的字符有限,其中就不支持中文字符,因此才保留了UTF16兜底)。

优化空间的好处

单位时间内,
减少空间->减少触发GC的次数->减少Stop the world activity的次数->提高系统性能

延伸

java设计者最开始设计char类型的时候,就是冲着用USE-2(utf-16的前身)来表示unicode中的所有字符,事与愿违,unicode不断收录新的字符,原有两个字节也不够用了,char类型也失去了其原有字符的语意,也许理解为code unit更合适。

原文地址:

https://www.zhihu.com/question/447224628/answer/1824574900

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值