龙泉建设工程有限公司网站,欢迎进入中国建设银行网站,领导高度重视网站建设,建设增塑剂网站上篇文章说gc日志以及arthas。
Arthas GC日志-JVM#xff08;十八#xff09;
一、常量池
常量池主要放两大类#xff1a;字面量和符号引用。
字面量就是由字母、数字等构成的字符串或者数值常量。
符号引用主要包含三类常量。
类和接口的全限定名。字段的名称和…上篇文章说gc日志以及arthas。
Arthas GC日志-JVM十八
一、常量池
常量池主要放两大类字面量和符号引用。
字面量就是由字母、数字等构成的字符串或者数值常量。
符号引用主要包含三类常量。
类和接口的全限定名。字段的名称和描述符。方法的名称和描述符。 字符串常量池
Jkd1.6之前有永久代运行时常量池在永久代运行时常量池里包含字符串常量池。
Jdk1.7有永久代但逐步去掉永久代字符串常量池从运行时常量池分离到堆里。
Jdk1.8之后无永久代运行时常量池在元空间字符串常量池还在堆里。 1、字符串常量池设计思想
因为字符串和对象分配一样要耗费时间和空间代价较大作为基础数据频繁创建字符串对代码性能有影响为了提高效率则为字符串开辟字符串缓存区创建字符串前先在字符串常量池判断是否存在存在则引用该实例不存在则放入字符串缓冲区。 实际操作
String s “zhangsan”;
这时候s指向字符串常量池的引用。使用的时候先会去字符串常量池equals比较一样则直接返回不一样才会放入字符串缓冲区。 String s1 new String(“zhangsan”);
S1指向内存对象引用。
这种方法会保证字符串常量池和堆都有这个对象没有就创建最后返回堆内存中对象引用。
先去字符串常量池创建字符串对象再去堆里创建字符串对象“zhangsan” 最后直接将内存中的引用返回。 String s1new String(“zhangsan”);
String s2s1.intern();
System.out.println(s1 s2)//false
Intern方法是native修饰先去常量池先找字符串对象有的话直接返回没有直接返回指向字符串s1堆里对象的引用。 再看特殊的例子 String str2 new StringBuilder(“计算机”).append(“技术”).toString();
System.out.println(str2 str2.intern())
这个为什么输出的true呢
在堆内存是有StringBuilder对象但是会被gc回收toString则会new String()这个才是正在返回对象引用。
“计算机技术”没有在常量池中但在heap堆中intern则会直接返回堆的引用所以true。
而“java”属于关键字早就在常量池引用对比则是false。