网易首页 > 网易号 > 正文 申请入驻

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

0
分享至

如果你不是 Java8 的钉子户,你应该早就发现了:String 类的源码已经由char[]优化为了byte[]来存储字符串内容,为什么要这样做呢?

开门见山地说,从char[]byte[],最主要的目的是为了节省字符串占用的内存。内存占用减少带来的另外一个好处,就是 GC 次数也会减少。

一、为什么要优化 String 节省内存空间

我们使用jmap -histo:live pid | head -n 10命令就可以查看到堆内对象示例的统计信息、查看 ClassLoader 的信息以及 finalizer 队列。

以我正在运行着的编程喵喵项目实例(基于 Java 8)来说,结果是这样的。

其中 String 对象有 17638 个,占用了 423312 个字节的内存,排在第三位。

由于 Java 8 的 String 内部实现仍然是char[],所以我们可以看到内存占用排在第 1 位的就是 char 数组。

char[]对象有 17673 个,占用了 1621352 个字节的内存,排在第一位。

那也就是说优化 String 节省内存空间是非常有必要的,如果是去优化一个使用频率没有 String 这么高的类库,就显得非常的鸡肋。

二、byte[]为什么就能节省内存空间呢?

众所周知,char 类型的数据在 JVM 中是占用两个字节的,并且使用的是 UTF-8 编码,其值范围在 '\u0000'(0)和 '\uffff'(65,535)(包含)之间。

也就是说,使用char[]来表示 String 就导致了即使 String 中的字符只用一个字节就能表示,也得占用两个字节。

当然了,仅仅将char[]优化为byte[]是不够的,还要配合 Latin-1 的编码方式,该编码方式是用单个字节来表示字符的,这样就比 UTF-8 编码节省了更多的空间。

换句话说,对于:

String name = "jack";

这样的,使用 Latin-1 编码,占用 4 个字节就够了。

但对于:

String name = "小二";

这种,木的办法,只能使用 UTF16 来编码。

针对 JDK 9 的 String 源码里,为了区别编码方式,追加了一个 coder 字段来区分。


* 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 会根据字符串的内容自动设置为相应的编码,要么 Latin-1 要么 UTF16。

也就是说,从char[]byte[]中文是两个字节,纯英文是一个字节,在此之前呢,中文是两个字节,英文也是两个字节

三、为什么用UTF-16而不用UTF-8呢?

在 UTF-8 中,0-127 号的字符用 1 个字节来表示,使用和 ASCII 相同的编码。只有 128 号及以上的字符才用 2 个、3 个或者 4 个字节来表示。


  • 如果只有一个字节,那么最高的比特位为 0;

  • 如果有多个字节,那么第一个字节从最高位开始,连续有几个比特位的值为 1,就使用几个字节编码,剩下的字节均以 10 开头。

具体的表现形式为:

  • 0xxxxxxx:一个字节;

  • 110xxxxx 10xxxxxx:两个字节编码形式(开始两个 1);- 1110xxxx 10xxxxxx 10xxxxxx:三字节编码形式(开始三个 1);

  • 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx:四字节编码形式(开始四个 1)。

也就是说,UTF-8 是变长的,那对于 String 这种有随机访问方法的类来说,就很不方便。所谓的随机访问,就是charAt、subString这种方法,随便指定一个数字,String要能给出结果。如果字符串中的每个字符占用的内存是不定长的,那么进行随机访问的时候,就需要从头开始数每个字符的长度,才能找到你想要的字符。

那有小伙伴可能会问,UTF-16也是变长的呢?一个字符还可能占用 4 个字节呢?

的确,UTF-16 使用 2 个或者 4 个字节来存储字符。

  • 对于 Unicode 编号范围在 0 ~ FFFF 之间的字符,UTF-16 使用两个字节存储。

  • 对于 Unicode 编号范围在 10000 ~ 10FFFF 之间的字符,UTF-16 使用四个字节存储,具体来说就是:将字符编号的所有比特位分成两部分,较高的一些比特位用一个值介于 D800~DBFF 之间的双字节存储,较低的一些比特位(剩下的比特位)用一个值介于 DC00~DFFF 之间的双字节存储。

但是在 Java 中,一个字符(char)就是 2 个字节,占 4 个字节的字符,在 Java 里也是用两个 char 来存储的,而String的各种操作,都是以Java的字符(char)为单位的,charAt是取得第几个char,subString取的也是第几个到第几个char组成的子串,甚至length返回的都是char的个数。

所以UTF-16在Java的世界里,就可以视为一个定长的编码。

来源:https://www.zhihu.com/question

/447224628

END

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
尿毒症是喝出来的?医生告诫:即便是铁打的肾,这3种水也要少喝

尿毒症是喝出来的?医生告诫:即便是铁打的肾,这3种水也要少喝

莫将离
2024-06-01 23:41:40
张艺谋将执导科幻大作《三体》

张艺谋将执导科幻大作《三体》

澎湃新闻
2024-06-16 10:56:32
特瓦斯:贝林厄姆赢得金球一点不奇怪,他比贝克汉姆技术好

特瓦斯:贝林厄姆赢得金球一点不奇怪,他比贝克汉姆技术好

懂球帝
2024-06-16 19:10:34
最新开通!4小时38分,武汉直达

最新开通!4小时38分,武汉直达

鲁中晨报
2024-06-16 16:47:03
更名!深圳理工大学申请“圳理路”

更名!深圳理工大学申请“圳理路”

王晓爱体彩
2024-06-16 17:08:15
回顾:广东男子开车接女友,女友和蓝颜知己聊不停:男子上车就走

回顾:广东男子开车接女友,女友和蓝颜知己聊不停:男子上车就走

佑宛故事汇
2024-06-15 17:14:55
数学竞赛组委会回应姜萍入围决赛,姜萍决赛或将角逐韦神获奖赛道 :决赛难度相当于数学博士资格考试

数学竞赛组委会回应姜萍入围决赛,姜萍决赛或将角逐韦神获奖赛道 :决赛难度相当于数学博士资格考试

荔枝新闻
2024-06-14 18:25:44
A股:刚刚,最新发声!下周大盘会不会反弹?四大驱动因素来了

A股:刚刚,最新发声!下周大盘会不会反弹?四大驱动因素来了

兵哥闲聊
2024-06-16 08:16:26
回顾:男子炫耀大14岁老婆,风韵犹存,网友:姐弟恋也吃香

回顾:男子炫耀大14岁老婆,风韵犹存,网友:姐弟恋也吃香

夫妻谈资局
2024-06-16 15:11:20
上海女子请人上门灭白蚁崩溃:几百元就能解决,对方竟收了9000元!网友:按只收费?

上海女子请人上门灭白蚁崩溃:几百元就能解决,对方竟收了9000元!网友:按只收费?

上海圈
2024-06-15 12:38:41
基因无法骗人!看《爸去哪儿》7位萌娃,10年后颜值差距一目了然

基因无法骗人!看《爸去哪儿》7位萌娃,10年后颜值差距一目了然

贾文彬的史书
2024-06-15 20:34:59
都是花言巧语,别再“尬吹”毛东东了

都是花言巧语,别再“尬吹”毛东东了

一枚小吏
2024-06-13 09:44:46
比肩库里!总决赛单节命中5记三分,下一场他要被基德重用了

比肩库里!总决赛单节命中5记三分,下一场他要被基德重用了

刺头体育
2024-06-16 18:46:11
大S求复合遭筱梅高调回怼,高冷形象崩塌,悔之晚矣

大S求复合遭筱梅高调回怼,高冷形象崩塌,悔之晚矣

综艺拼盘汇
2024-06-15 18:12:32
美联储,突传重磅!

美联储,突传重磅!

券商中国
2024-06-15 14:28:48
22岁小伙雇45岁保姆后,整天不出门在家过二人世界

22岁小伙雇45岁保姆后,整天不出门在家过二人世界

牛城王小帅
2024-06-12 13:48:47
沃夫昌斯克俄军被围!火力优势降至5:1,小妇人们又给普京添堵

沃夫昌斯克俄军被围!火力优势降至5:1,小妇人们又给普京添堵

鹰眼Defence
2024-06-16 17:26:54
确定了!张艺谋!

确定了!张艺谋!

中国基金报
2024-06-16 14:37:55
诺贝尔奖获得者科斯:虽不知我还能活多久,但中国不会让我失望

诺贝尔奖获得者科斯:虽不知我还能活多久,但中国不会让我失望

黄丽搞笑小能手
2024-06-08 07:45:21
中国第一个被终身监禁的“大老虎”,索贿2.5亿元!曾将价值5000亿铅矿贱卖给“黑老大”

中国第一个被终身监禁的“大老虎”,索贿2.5亿元!曾将价值5000亿铅矿贱卖给“黑老大”

天闻地知
2024-06-05 10:06:04
2024-06-16 20:04:49
程序员乔戈里
程序员乔戈里
本人百度java工程师
1633文章数 8903关注度
往期回顾 全部

科技要闻

iPhone 16会杀死大模型APP吗?

头条要闻

凯特王妃患癌后首次露面 小王子跳舞抢镜被姐姐制止

头条要闻

凯特王妃患癌后首次露面 小王子跳舞抢镜被姐姐制止

体育要闻

没人永远年轻 但青春如此无敌还是离谱了些

娱乐要闻

上影节红毯:倪妮好松弛,娜扎吸睛

财经要闻

打断妻子多根肋骨 上市公司创始人被公诉

汽车要闻

售17.68万-21.68万元 极狐阿尔法S5正式上市

态度原创

艺术
教育
旅游
公开课
军事航空

艺术要闻

穿越时空的艺术:《马可·波罗》AI沉浸影片探索人类文明

教育要闻

南医大被罚老师因救人迟到受处分 校方第二天删除通告 律师发话

旅游要闻

@毕业生,江苏这些景区可享免票或优惠

公开课

近视只是视力差?小心并发症

军事要闻

以军宣布在加沙南部实行"战术暂停"

无障碍浏览 进入关怀版