ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

String的内存分配

2020-05-26 22:58:01  阅读:221  来源: 互联网

标签:常量 s2 s1 s4 内存 字符串 分配 String



String 的String pool (字符串常量池)是一个固定大小的HashTable,jdk6 中是默认的数组长度是1009
如果放入String pool 中的String太多,会造成hash冲突严重,导致链表很长,链表长了对于数据的更新和读取都是有性能的下降 可以通过-XX:StringTableSize参数设置大小
jdk8 开始默认的StringTable的长度是60013,1009是可设置的最小值,如果设置的值小于这个值是不允许的


java语言有8中基本类型和一种比较特殊的类型String,这些类型为了使他们在运行中更快都提供了常量池的概念,常量池类似于java系统级别提供的缓存
直接通过双引号声明出来的String对象会直接存储在常量池中,称为字符串字面量
不是通过双引号声明的String对象可以使用String提供的intern方法往常量池中放入字符串
在java6中,字符串常量池是存储在永久代中
在java7中,常量池的位置调整到java堆中
java8调整概念为元空间,字符串常量在堆中

为什么调整
1)permSize默认比较小 2)永久代GC回收频率低

 

关于字符串拼接

1.字符串拼接字符串的结果是放在常量池中,原理是编译期优化
String s1 = "a"+"b"+"c";
String s2 = "abc";
s1 == s2 //true

2.如果拼接前后出现变量,则结果是在堆中,相当于在堆空间中new String()
String s1 = "a";
String s2 = "b";
String s3 = "ab;
String s4 = s1+s2;
s3==s4//false

String s4 = s1+s2的执行细节:
1)StringBUilder s = new StringBuilder;
2)s.append("a");
3)s.append("b");
4)s.toString

3.字符串拼接操作不一定使用StringBuilder,如果字符串前后都是字符串常量或者常量引用
则仍然适用编译期优化

final String s2 = "b";
final String s3 = "ab;
String s4 = s1+s2;
s3==s4//true
final修饰了s1 和s2,在编译期就确定了,可以理解为一个常量


4.intern方法判断字符串常量池中是否在字符串,如果存在,则返回常量池中的地址,如果不存在
则在常量池中放入,并返回常量池中存在该对象的地址

标签:常量,s2,s1,s4,内存,字符串,分配,String
来源: https://www.cnblogs.com/wangflower/p/12969264.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有