Java虚拟机(三)
作者:互联网
特性:
- 常量池中的字符串仅是符号, 第一次用到时才会变为对象
- 利用串池机制, 来避免重复创建字符串对象
- 字符串变量拼接的原理是StringBuilder(1.8)
- 字符串常量拼接的原理是编译期优化
- 可以使用intern方法, 主动将串池中还没有的字符串对象放入串池.
- 1.8将这个字符串对象尝试放入串池, 如果有则并不会放入, 如果没有则放入串池中, 会把串池中的对象返回
- .8将这个字符串对象尝试放入串池, 如果有则并不会放入, 如果没有会把此对象复制一份,放入串池中, 会把串池中的对象返回
public class Demo_4 {
public static void main(String[] args) {
String x="ab";
/**
* 动态创建放入堆中, new String("a"),new String("b"),new String("ab")
*/
//["a","b","new String("b")"]
String s1=new String("a")+new String("b");
String s2=s1.intern();//将字符串对象尝试放入串池, 如果没有就放入, 有就不放入
System.out.println(s1==x);// false
System.out.println(s2==x);// true
}
}
5.6 StringTable
1.6 中在永久代, 1.8 在堆中
5.7 StringTable 垃圾回收
StringTable 会发生垃圾回收
5.8 StringTable性能调优
- 在StringTable 底层实现的是数组+链表, 可以通过调虚拟机的参数来提高StringTable 的性能
-XX:StringTableSize=1000
调整 -XX:StringTableSize=桶的个数
-
考虑字符串对象是否入池
如果有大量重复的字符串,可以考虑把字符串接入串池, 来减少内存的占用.
6. 直接内存
6.1 定义
直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分, 也不是<<Java虚拟机规范>>中定义的内存, 而是本机直接内存.
- 常见于NIO操作时, 用于数据缓冲区
- 分配回收成本较高, 但读写性能高
- 不受JVM内存回收管理
6.2 分配和回收原理
- 使用Unsafe对象完成直接内存的分配回收, 并且回收需要主动调用freeMemory方法
- ByteBuffer的实现内部, 使用了Cleaner(虚引用)来监测ByteBuffer对象,一旦ByteBuffer 对象被垃圾回收, 那么就会由ReferenceHandle线程通过Cleaner的clean方法调用freeMemory来释放直接内存
垃圾回收
1. 如何判断对象可以回收
1.1 引用计数法
给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器都为0的对象就是不再被使用的,垃圾收集器将回收该对象使用的内存
Java虚拟机并不是通过引用计数算法来判断对象是否存活的
标签:Java,String,对象,虚拟机,串池,内存,字符串,放入 来源: https://blog.csdn.net/OYO_OYO____/article/details/117432761