JVM虚拟机理解学习

垃圾回收

1.如何判断对象为垃圾对象

1.1引用计数法
1.2可达性分析法
1.1引用计数法

在对象中添加一个引用计数器,当存在引用对象时,引用计数器的值+1,引用失效时,计数器-1

/**
 * @PACKAGE_NAME: PACKAGE_NAME
 * @Description:
 * @Author: liangxu
 * @Date: 2021/8/30 11:52 上午
 * @Version: V1.0
 */
public class JVMTest {
    private Object instance;

    public static void main(String[] args) {
		//1.对象进行两次引用
        JVMTest t1 = new JVMTest();
        JVMTest t2 = new JVMTest();
		//对象间互相引用  此时达到的效果为t1引用计数器为2、t2引用计数器为2   
        t1.instance = t2;
        t2.instance = t1;
		//将对象设置为null后,引用计数器-1,t1引用计数器为1、t2引用计数器为1  
        t1 = null;
        t2 = null;
		//结论:
		/**
		* 如果JVM采用计数器进行内存释放的话,则存在不会被释放的垃圾对象占用内存,那么如何验证JVM是否使用了计数器进行内存管理呢,我们可以打印JVM观察。
		*/
        System.gc();
    }
}

idea垃圾回收配置:
在这里插入图片描述
在这里插入图片描述
-Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8 -XX:+PrintGCDetails
-XX:+PrintGCDetails GC收集器
-XX:+UseSerialGC Serial收集器打印
-Xms20M -Xmx20M 堆内存
-Xmn10M 新生代内存
-XX:SurvivorRatio=8 Eden区域大小
如下图:
在这里插入图片描述
配置完成后,应用->运行。
在这里插入图片描述
从结果中我们可以看出:
我们当前的JVM对

1.2可达性分析算法

从GCRoot根节点向下检索,如不存在引用链,不能检索到的对象将被释放。
在这里插入图片描述

2.如何回收

1.1回收策略
	1.1.1标记-清除算法
	1.1.2复制算法
	1.1.3标记-整理算法
	1.1.4分代手机算法
1.2垃圾回收器
	1.1.1Serial
	1.1.2Parnew
	1.1.3Cms
	1.1.4G1

注:关于新声代老年代查看文档介绍

1.1 回收策略
1.1.1标记-清除算法(老年代)
		效率问题
		空间问题

在这里插入图片描述

请添加图片描述

上图我们可以看出,红色代表使用的,黄色代表标记的,白色代表未使用的。当黄色被清除后,堆内存变成一块一块,占用率降低。并且当它再不停检索时,因为块不断增加,导致效率低下

缺点:两次扫描,严重浪费时间,

1.1.2复制算法(新生代)

1.堆
1.1新声代
Eden 伊甸园
Survivor 存活区
Tenured Gen
1.2老生代
2.方法区
3.栈 本地方法栈 程序计数器
在这里插入图片描述
提高内存利用率,将内存分为3大块。
Eden用来存储内存初始化对象。在回收时,将在使用的的内存,存放到Survivor,如果在使用大于在使用的内存,则会借用Tenured Gen“内存担保”存储。

请添加图片描述

请添加图片描述
好处:没有内存的碎片
坏处:浪费内存空间:多了一半空间永远是空的to。假设对象100%存活(极端情况)

复制算法最佳使用场景:对象存活度较低的时候:新生代

1.1.3标记-整理算法(老年代)

在这里插入图片描述
使用和未使用的移动到两端,最后清除未使用的。高效。

总结:
内存效率:复制算法->标记清除算法->标记压缩算法(时间复杂度)
内存整齐度:复制算法=标记压缩算法->标记清除算法
内存利用率:标记压缩算法=标记清除算法->复制算法
难道没有最优的算法吗?
答案:没有最好的算法,只有最合适的算法
GC分代收集算法

年轻代:
存活率低,采用复制算法

老年代:
区域大,存活率高,采用标记清除(内存碎片不是太多)+标记压缩混合实现

1.1.4分代收集算法

分代收集算法即针对新生代采用复制算法,针对老年代采用标记整理算法。

1.2 垃圾回收器
1.1.1Serial收集器(客户端收集)

最基本,发展最悠久
单线程垃圾收集器

1.1.2Parnew

多线程收集

效率相比Serial要高,但如果在客户端的话,建议使用Serial
在这里插入图片描述

1.1.3Parallel Scavenge 收集器(服务器收集器)

复制算法(新生代收集器)
多线程收集器
达到可控制的吞吐量(吞吐量:CPU用于运行用户代码的时间与CPU消耗的总时间的比值 吞吐量=(执行用户代码时间)/(执行用户代码的时间+垃圾回收所占用的时间))

-XX:MaxGFPauseMillis 垃圾收集器最大停顿时间

-XX:CGTimeRatio 吞吐量大小

1.1.3Cms收集器(Concurrent Mark Sweep 并发标记清除)

并发收集器,用于回收老年代内存。
1.工作过程
初始标记
并发标记(边扔垃圾边打扫)
重新标记
并发清理
优点
并发收集
低停顿
缺点
占用大量的CPU资源
无法处理浮动垃圾
出现Concurrent Mode Failure (并发清理时,会出现问题)
空间碎片

在这里插入图片描述
初始标记:可被回收的对象。(可达性分析法)
并发标记
重新标记:因程序继续运行而导致的变动的对象进行重新标记
并发清理

1.1.4 G1收集器

注:重量级

优势:
1.并行与并发
2.分代收集
3.空间整合(标记整理清除)
4.可预测的停顿
步骤:
1.初始标记
2.并发标记
3.最终标记
4.筛选回收
在这里插入图片描述
如上图:在对象写入时,通过可达性分析发判断,如果对象的引用在不同的内存块中,则记录入remeber set表中。从而达到不需要垃圾回收筛选时,不需要扫描所有的内存块。提高效率。

3.何时回收

引用计数法
在对象中添加一个引用计数器,当存在引用对象时,引用计数器的值+1,引用失效时,计数器-1

JVM的内存分配

1.优先分配到eden

2.大对象直接分配到老年代

3.上期存活的对象分配到老年代

4.空间分配担保

5.动态对象年龄判断

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值