黑马JVM总结(八)

(1)StringTable面试题

1.8

1.6时

(2)StringTable的位置

jvm1.6时StringTable是常量池的一部分,它随着常量池存储在永久代当中,在1.7、1.8中从永久代变成了堆中,为什么做这个更改呢?因为永久代的内存效率很低,永久代是在Full GC的时候才会触发永久代的垃圾回收,Full GC只有等到老年代的空间不足时才会触发,触发的时机比较晚导致StringTable的回收效率不高

StringTable用的非常的频繁它里面存储的都是字符串常量,我们java程序中字符串常量对象都会分配到StringTable中,它的回收效率不高会占用大量的内存,它的效率不高,会产生永久代的内存不足,基于这个缺点,把它转到堆里面,在堆里面只需要Minor GC就可以触发垃圾回收,一些常量池中的用不到的字符串对相关就可以垃圾回收,大大减轻了字符串对内存的占用

下面用例子证明一下StringTable串池的位置:我们把字符串放到集合中不让它回收

上面没有触发内存不足,是因为循环次数不足以触发,我们在1.6的情况下吧永久代的内存设置小一些,就会暴露内存不足的现象

报的是永久代内存溢出

切换到1.8环境下:设置最大参数

报这个GC overhead.... 这个是jvm垃圾回收的规则是由虚拟机参数控制的:

有个虚拟机参数

可以 关闭这个参数:

再次运行堆内存空间不足

通过以上就可以证明StringTable1.8用的是空间,1.6用的是永久代

(3)String_Table的垃圾回收

StringTable也会受到垃圾回收的管理的,当内存空间不足时StringTable中哪些没有被引用的字符串常量也会被垃圾回收

-Xmx10m:设置虚拟机堆内存的最大值

-XX:+:PrintStringStatistics打印字符串表的统计信息,通过它我们就可以看到串池中的字符串个数,及大小信息

-XX:+PrintGCDetails -verbose:gc 打印垃圾回收的信息把垃圾回收的次数啊时间啊显示出来

堆内存占用,垃圾回收信息

符号表:类的字节码里类名、方法名、变量名

StringTable的统计信息

StringTable的底层类似我们的HashTable的实现:数组+列表

数组的个数称为桶:

StringTable是以哈希表的方式存储数据的通的个数叫做buckets

存储的字符串对象:entries个数

字符串常量个数:literals

上面的代码我们什么都没有做,但是有数据,java程序在运行时类名,方法名,这些数据也是以字符串常量的形式表示的他们也存在串池中已经有那么多字符串对象了

我们写入代码:加入串池,观看前后串池的字符串常量个数变化

变为1854 ,此时没有触发垃圾回收,我们可以进行修改加入串池的个数

修改为存入串池为10000个:当10兆的堆内存可能存不下,会触发垃圾回收,我们可以看到存入串池的字符串个数,并没有全部存入7226

为什么只存入七千多呢,因为触发了垃圾回收

通过以上案例我们可以得出StringTable也是可以发生垃圾回收的

相关推荐
流星52112210 小时前
GC 如何判断对象该回收?从可达性分析到回收时机的关键逻辑
java·jvm·笔记·学习·算法
JanelSirry10 小时前
我的应用 Full GC 频繁,怎么优化?
jvm
JH307310 小时前
jvm,tomcat,spring的bean容器,三者的关系
jvm·spring·tomcat
DKPT14 小时前
JVM直接内存和堆内存比例如何设置?
java·jvm·笔记·学习·spring
siriuuus14 小时前
JVM 垃圾收集器相关知识总结
java·jvm
小满、17 小时前
什么是栈?深入理解 JVM 中的栈结构
java·jvm·1024程序员节
百花~1 天前
JVM(Java虚拟机)~
java·开发语言·jvm
每天进步一点点dlb1 天前
JVM中的垃圾回收算法和垃圾回收器
jvm·算法
漫漫不慢.1 天前
蓝桥杯-16955 岁月流转
java·jvm·蓝桥杯
boy快快长大2 天前
【JVM】线上JVM堆内存报警,占用超90%
jvm