🌈hello,你好鸭,我是Ethan,西安电子科技大学大三在读,很高兴你能来阅读。
✔️目前博客主要更新Java系列、项目案例、计算机必学四件套等。
🏃人生之义,在于追求,不在成败,勤通大道。加油呀!
🔥个人主页:Ethan Yankang
🔥推荐:史上最强八股文||一分钟看完我的几百篇博客
🔥温馨提示:划到文末发现专栏彩蛋 点击这里直接传送
🔥本篇概览:详细讲解了堆空间分代思想与堆中对象的分配策略以及详细讲解了jstat的栏目意义。。🌈⭕🔥
【计算机领域一切迷惑的源头都是基本概念的模糊,算法除外】
🌈章节引出:
前一篇章:《剑指JVM》——第7章——图解对象分配到消亡的全过程8大步——堆5——运行时数据区篇17-CSDN博客
🌈章节速览:
7.6 堆空间分代思想
为什么需要把Java 堆分代?不分代就不能正常工作了吗?经研究,不同的对象生命周期不同。70%~ 99%的对象是临时对象。其实不分代完全可以,分代的唯一理由就是优化性能。
如果没有分代,那所有的对象都在一块,就如同把一个学校的人都关在一个教室。GC的时候要找到哪些对象没用,这样就需要对堆的所有区域进行扫描。而很多对象都是“朝生夕死”的,如果分代的话,把新创建的对象放到某一地方,当GC的时候先把这块存储“朝生夕死”对象的区域进行回收,这样就会腾出很大空间。
7.7 堆中对象的分配策略
如果对象在 Eden 区出生,并经过第一次 MinorGC后仍然存活,并且能被 Survivor 区容纳的话,将被移动到 Survivor 区中,并将对象年龄设为1。对象在 Survivor 区中每经过一次 Minor GC年龄就增加1岁,当它的年龄增加到一定程度时(默认为15岁,其实每个JVM、每个GC都有所不同),就会被晋升到老年代中。对象晋升老年代的年龄值,可以通过“-XX:MaTenuringThreshold”来设置,也会有其他情况直接分配对象到老年代。
对象分配策略如下所示:
- (1)优先分配到 Eden 区。
- (2)大对象直接分配到老年代,在开发过程中应尽量避免程序中出现过多的大对象
- (3)长期存活的对象分配到老年代。
- (4)通过动态对象年龄判断,如果Survivor区中相同年龄的所有对象的大小总和大于 Survivor区的一半,年龄大于或等于该年龄的对象可以直接进入老年代,无须等MaxTenuringThreshold 中要求的年龄。
代码演示:
下面我们通过代码演示大对象直接进入老年代的情景:
/**测试:大对象直接进入老年代
*-Xms60m -Xmx60m -XX:NewRatio=2-XX:SurvivorRatio=8 -XX:+PrintGCDetails
*/
public class YoungOldAreaTest {
public static void main(String[] args) {
byte[] buffer = new byte[1024 * 1024 * 20]; // 20M
try {
Thread.sleep(1000000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
如图,下面的old uesr=21504>20480=20M,所有对象直接是分配到老年代,Eden存不下。
讲解jstat的栏目
S0C S1C S0U S1U EC EU OC OU MC MU CCSC
CCSU YGC YGCT FGC FGCT GCT
这些是与 Java 虚拟机(JVM)的垃圾回收(GC)和内存管理相关的一些指标和参数:
- s0c:年轻代中第一个 survivor(幸存区)的容量(单位:kb)。
- s1c:年轻代中第二个 survivor(幸存区)的容量(单位:kb)。
- s0u:年轻代中第一个 survivor(幸存区)目前已使用空间(单位:kb)。
- s1u:年轻代中第二个 survivor(幸存区)目前已使用空间(单位:kb)。
- ec:年轻代中 eden(伊甸园)的容量(单位:kb)。
- eu:年轻代中 eden(伊甸园)目前已使用空间(单位:kb)。
- oc:old 代(老年代)的容量(单位:kb)。
- ou:old 代目前已使用空间(单位:kb)。
- mc:元数据区(metaspace)已经 committed 的内存空间。
- mu:元数据区的使用量。
- ccsc:压缩 class(compressed class space)committed 的内存空间。
- ccsu:压缩 class 已使用的内存空间。
- ygc:从应用程序启动到采样时年轻代中垃圾回收(GC)的次数。
- ygct:从应用程序启动到采样时年轻代中垃圾回收所用的时间(单位:s)。
- fgc:从应用程序启动到采样时 old 代(全 GC)垃圾回收的次数。
- fgct:从应用程序启动到采样时 old 代垃圾回收所用的时间(单位:s)。
- gct:从应用程序启动到采样时垃圾回收用的总时间(单位:s)。
详细讲解CCSC、CCSU
在 64 位平台上,HotSpot 使用了两项压缩优化技术,分别是compressed object pointers
(“compressed oops”)和compressed class pointers
。
compressed class pointers
指的是,每个 Java 对象的头部有一个引用指向元空间(metaspace)中的klass
结构。当使用了compressed class pointers
时,这个引用是 32 位的值。为了找到真正的 64 位地址,需要加上一个基准值(base 值)。
然而,这项技术对klass
的分配带来了问题:由于 32 位地址只能访问到 4GB 的空间,所以最大只允许 4GB 的klass
地址。这意味着 JVM 需要向元空间分配一个连续的地址空间。但当通过调用系统接口malloc(3)
或mmap(3)
从系统申请内存时,操作系统可能返回任意一个地址值,它并不能保证在 4GB 的范围内。
因此,只能用一个mmap()
来申请一个区域单独用来存放klass
对象。由于需要提前知道这个区域的大小,而且不能超过 4GB,这种方式是不能扩展的,因为这个地址后面的内存可能是被占用的。
只有klass
结构有这个限制,对于其他的类元数据(class metadata)则没有必要,因为只有klass
实例是通过 Java 对象头部中的压缩指针访问的,其他的元数据都是通过 64 位的地址进行访问,所以它们可以被放到任意的地址上。
基于此,将元空间分为了两个区域:
non-class part
:包含其他所有的元数据;class part
:存放klass
对象,需要一个连续的不超过 4GB 的内存,这个区域被称作compressed class space
。
compressed class space
空间的大小可以通过-XX:CompressedClassSpaceSize
指定,其默认值是 1GB。需要注意的是,这里的 1GB 并不是真正使用了操作系统的 1GB 物理内存,而是虚拟地址映射。
另外,有两个相关的开关:
-XX:+UseCompressedOops
:允许对象指针压缩;-XX:+UseCompressedClassPointers
:允许类指针压缩。
它们默认都是开启的,也可以手动关闭。如果不允许类指针压缩,那么将没有compressed class space
这个空间,并且-XX:CompressedClassSpaceSize
这个参数无效。
同时,-XX:-UseCompressedClassPointers
需要搭配-XX:+UseCompressedOops
,但反过来则不是必须的。也就是说,可以只压缩对象指针,而不压缩类指针。这可能是因为从直觉上来说,压缩对象指针能获得较大的收益,相对更为重要。
此外,对象指针压缩要求堆小于 32GB,如果堆大于等于 32GB,那么对象指针压缩和类指针压缩都会被关闭。
在使用jstat
命令查看 Java 虚拟机的统计信息时,ccsc
(Compressed Class Space Committed)表示压缩类空间(compressed class space)已提交的内存空间大小。它反映了当前实际为compressed class space
分配的内存量。通过观察ccsc
的值,可以了解到compressed class space
的使用情况,以便进行内存管理和优化。如果发现ccsc
的值接近或达到了设置的上限,可能需要考虑调整相关的内存参数,或者优化类的数量和大小等,以避免出现内存不足的情况。
💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖
热门专栏推荐
🌈🌈计算机科学入门系列 关注走一波💕💕
🌈🌈CSAPP深入理解计算机原理 关注走一波💕💕
🌈🌈微服务项目之黑马头条 关注走一波💕💕
🌈🌈redis深度项目之黑马点评 关注走一波💕💕
🌈🌈JAVA面试八股文系列专栏 关注走一波💕💕
🌈🌈JAVA基础试题集精讲 关注走一波💕💕
🌈🌈代码随想录精讲200题 关注走一波💕💕
总栏
🌈🌈JAVA基础要夯牢 关注走一波💕💕
🌈🌈JAVA后端技术栈 关注走一波💕💕
🌈🌈JAVA面试八股文 关注走一波💕💕
🌈🌈JAVA项目(含源码深度剖析) 关注走一波💕💕
🌈🌈计算机四件套 关注走一波💕💕
🌈🌈数据结构与算法 关注走一波💕💕
🌈🌈必知必会工具集 关注走一波💕💕
🌈🌈书籍网课笔记汇总 关注走一波💕💕
📣非常感谢你阅读到这里,如果这篇文章对你有帮助,希望能留下你的点赞👍 关注❤收藏✅ 评论💬,大佬三连必回哦!thanks!!!
📚愿大家都能学有所得,功不唐捐!