目录
简介
JVM 垃圾回收就是JVM中有一些线程用来处理 程序运行过程中 堆内存不够的情况,堆内存不够,就把一些不用的堆上的对象清除腾出空间容纳新对象。
所以JVM 垃圾回收就需要判断哪些对象是垃圾,采用哪种策略去回收这些垃圾,回收的时候还需要注意停顿时间,不要对正常的线程运行造成明显的影响。
如果最后发现在怎么清理也没有办法容纳新对象,那么就OOM。
没有垃圾回收时 堆的情况
public class Demo2_1_My {
private static final int _512KB = 512 * 1024;
private static final int _1MB = 1024 * 1024;
private static final int _6MB = 6 * 1024 * 1024;
private static final int _7MB = 7 * 1024 * 1024;
private static final int _8MB = 8 * 1024 * 1024;
// -Xms20M -Xmx20M -Xmn10M -XX:+UseSerialGC -XX:+PrintGCDetails -verbose:gc -XX:-ScavengeBeforeFullGC
public static void main(String[] args) throws InterruptedException {
}
}
配置 VM options为
-Xms20M -Xmx20M -Xmn10M -XX:+UseSerialGC -XX:+PrintGCDetails -verbose:gc
使用的是串行的垃圾回收器。
堆大小为20M 新生代大小为10M
添加 一个7MB的对象
在此基础上添加 一个7MB的对象 应该会超过9MB,会触发垃圾回收,如果回收完毕还能容纳7MB对象,那么就会分配。
添加 一个8MB的对象
在此基础上添加 一个8MB的对象 应该也会超过9MB,应该会触发垃圾回收,但实际没有触发,原因是大对象直接进入老年代。
也可以配置参数设定直接进入老年代的阈值():(仅适用于Serial和ParNew两款新生代收集器)
-XX:PretenureSizeThreshold=5M
超过5MB 直接进入老年代。
原因:
a. 大对象需要连续的内存空间,而新生代为了安放大对象可能需要多次进行GC,增加开销;
b. 新生代种伊甸园区和幸存者区常采用复制算法,需要经常复制对象到不同的区域,而大对象在复制时开销较大。
添加 一个7MB的对象 + 一个1MB的对象
7MB的年龄是1,在第二次垃圾回收的时候就进入了老年代,原因是:
如果在Survivor空间中相同年龄所有对象大小的总和大于 Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无须等到-XX: MaxTenuringThreshold中要求的年龄。
参考:
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/92778.html