JAVA垃圾回收机制

大家好,我是皮卡,这次分享的是JAVA垃圾回收机制,如果有需要或是感兴趣的话,就一起看下去吧~

目录

一、手动垃圾回收机制

二、自动垃圾回收机制

1、概念

2、判断哪些对象有用

3、finalize方法——final、finally、finalize区别

4、触发垃圾回收的条件

5、java中的释放资源与垃圾回收机制区别

6、减少GC垃圾回收开销


一、手动垃圾回收机制(C/C++)

手动:使用过的对象必须要程序员自己来回收

缺点:

1⃣️若程序员忘记及时回收——对象会一直在内存中,若程序运行时间很长,内存中存在大量垃圾,空间越来越满,之后创建的对象没有内存可用——>导致内存泄漏、降低系统性能

2⃣️程序员自己回收可能存在误收操作——导致系统崩溃

二、自动垃圾回收机制(Java)

1、垃圾回收机制(GC):通过自动垃圾回收算法对堆内存new出的且不再被引用的对象 进行回收

2、垃圾回收机制如何判断对象是否还有用?

      检查堆内存中空间是否充裕:

  • 足够,则不回收
  • 不足,通过算法检查是否有 已创建 且长时间未被引用的对象——>若长时间未被引用 且急需创建新的对象,垃圾回收机制就会将这些对象定为垃圾,会优先将这部分空间进行回收

3、垃圾回收机制在回收任何对象之前,总会先自动调用 finalize()方法(自动调用,不由程序员调用),调用该方法可以在垃圾回收同时打印日志等操作

注:finalize可以用来清理不是new出的对象所占用的内存,可以用来清理本地对象

本地对象:指的是在Java中调用非Java代码(C/C++)时创建的对象

 protected void finalize() throws Throwable { }

下面是我在一次面试中面试官问到我的问题,大家也可以看下~

final、finally、finalize的区别

final:修饰符,被final修饰的变量不能被修改,被final修饰的方法不能被重写,被final修饰的类不能被继承

finally:在异常处理时,用于最终进行收尾工作的代码块

finalize:Object中提供的方法,用于垃圾回收之前自动被垃圾回收器调用的方法

对象在内存中的状态转换【具体内容我们在下期分享】

4、触发垃圾回收的条件

  • 当没有线程在运行时,垃圾回收会被调用。因为垃圾回收在优先级最低的线程中进行,当应用忙时,垃圾回收不被调用(不是由程序员自己调用的),但除第二点
  • 堆内存不足时会触发垃圾回收机制

      自动回收机制——>程序员无法精确控制垃圾回收的执行,可以通过System.gc() 或 Runtime.getRuntime().gc() 来通知JVM进行垃圾回收,但系统是否进行垃圾回收依旧不确定

public class TestGC {
    public static void main(String[] args) {
        TestGC testGC = new TestGC();
        testGC = null;
        System.gc(); // 通知垃圾回收器来回收垃圾,但是否进行垃圾回收依旧不确定,因为这不是程序员控制的
    }

    @Override
    protected void finalize() throws Throwable {
        System.out.println("对象被GC回收");
    }
}

情况一:被回收

情况二:没有被回收

5、Java中释放资源与垃圾回收机制的区别

  • 垃圾回收只能释放内存中的资源,不能释放与内存无关的资源
  • 垃圾回收具有不确定性,程序员无法精确控制垃圾回收的执行,没有确定的回收时间
  • IO流资源不能被GC直接释放(IO流使用了虚拟机之外的资源,所以虚拟机无法通过垃圾回收释放资源),但可以通过finalize方法释放。该方法防止程序员忘记需要手动释放资源——依旧需要手动调用close方法释放资源。

上述说到finalize方法执行在垃圾回收机制之前,但垃圾回收机制具有不确定性,不确定什么时候进行垃圾回收。所以finalize方法无法保证对 手动需要释放的资源 进行及时回收。

protected void finalize() throws IOException {
        if ((fd != null) &&  (fd != FileDescriptor.in)) {
            /* if fd is shared, the references in FileDescriptor
             * will ensure that finalizer is only called when
             * safe to do so. All references using the fd have
             * become unreachable. We can call close()
             */
            close();
        }
    }

6、减少GC垃圾回收开销

  • 尽量不要显式调用System.gc()

      会增加GC的频率,但不能保证清除所有垃圾。GC也是一个线程,会消耗资源,可能会造成间歇性停顿次数(运行时是间歇进行的)。


好啦,就先到这里吧~
喜欢我的可以点赞、关注、收藏,如果有什么技术上的疑问,欢迎留言或私信~ 

我们下次见~

  • 8
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值