JVM相关(一)

本文深入探讨Java内存结构,解析垃圾回收机制的工作原理,包括finalize方法的作用,以及如何判断对象是否存活的两种方法:引用计数法和可达性算法。同时,详细介绍了三种垃圾回收策略:复制算法、标记清除算法和标记压缩算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. java内存结构

java内存结构

2. finalize
2.1 什么是垃圾回收机制

不定时去堆内存中清理不可达对象。不可达的对象并不会马上就会直接回收, 垃圾收集器在一个Java程序中的执行是自动的,不能强制执行,即使程序员能明确地判断出有一块内存已经无用了,是应该回收的,程序员也不能强制垃圾收集器回收该内存块。程序员唯一能做的就是通过调用System.gc 方法来"建议"执行垃圾收集器,但其是否可以执行,什么时候执行却都是不可知的

public class Test001 {

    //什么是不可达对象:没有被继续引用,没有存活,
    public static void main(String[] args) {
        Test001 obj = new Test001();
        obj = null; //不可达,提示jvm回收
        System.gc();//提示给gc进行回收垃圾  误区:提示垃圾回收机制进行回收,但不代表会立即回收
    }

    @Override
    protected void finalize() throws Throwable {
        //垃圾回收之前会执行的方法
        System.out.println("垃圾回收之前要执行了...");
    }
}

3. 如何判断对象是否存活
3.1 引用计数法

引用计数法就是如果一个对象没有被任何引用指向,则可视之为垃圾。这种方法的缺点就是不能检测到环的存在。

3.2 可达性算法

根搜索算法的基本思路就是通过一系列名为”GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。
在这里插入图片描述

4. 垃圾回收机制策略
4.1 复制算法

coping算法一般是使用在新生代中,因为新生代中的对象一般都是朝生夕死的,存活对象的数量并不多,这样使用coping算法进行拷贝时效率比较高。jvm将Heap 内存划分为新生代与老年代,又将新生代划分为Eden(伊甸园) 与2块Survivor Space(幸存者区) ,然后在Eden –>Survivor Space 以及From Survivor Space 与To Survivor Space 之间实行Copying 算法。 不过jvm在应用coping算法时,并不是把内存按照1:1来划分的,这样太浪费内存空间了。一般的jvm都是8:1。也即是说,Eden区:From区:To区域的比例是
始终有90%的空间是可以用来创建对象的,而剩下的10%用来存放回收后存活的对象。

1、当Eden区满的时候,会触发第一次young gc,把还活着的对象拷贝到Survivor From区;当Eden区再次触发young gc的时候,会扫描Eden区和From区域,对两个区域进行垃圾回收,经过这次回收后还存活的对象,则直接复制到To区域,并将Eden和From区域清空。
2、当后续Eden又发生young gc的时候,会对Eden和To区域进行垃圾回收,存活的对象复制到From区域,并将Eden和To区域清空。
3、可见部分对象会在From和To区域中复制来复制去,如此交换15次(由JVM参数MaxTenuringThreshold决定,这个参数默认是15),最终如果还是存活,就存入到老年代
注意: 万一存活对象数量比较多,那么To域的内存可能不够存放,这个时候会借助老年代的空间。
在这里插入图片描述

4.2 标记清除算法
4.3 标记压缩算法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值