java垃圾回收机制

垃圾收集器(GC)

Java中使用垃圾收集器来监视Java程序的运行,当对象不再使用时,就自动释放对象所使用的内存。

垃圾收集器是自动运行的,一般情况下,无须显示地请求垃圾收集器。调用System类中的静态gc()方法可以运行垃圾收集器,但这样并不能保证会立即回收指定对象。

因为不同的JVM实现者可能使用不同的算法管理GC,并且通常GC的线程优先级较低,JVM调用GC的策略也有很多种,有些是内存使用达到一定程度时才会执行GC,也有定时执行的,有的是平缓执行的,还有的是中断式执行的。

Java的垃圾回收机制是为所有的Java应用进程服务的,而不是为某个特定的进程服务的。因此,任何一个进程都不能命令垃圾回收机制做什么、怎么做或做多少。

在JVM垃圾收集器收集一个对象前,一般要求程序调用适当的方法释放资源,但在没有明确释放资源的情况下,Java提供了默认机制终止化该对象来释放资源,这个方法就是protected void finalize() throws Throwable。

垃圾收集算法

复制算法:

新生代GC基本都是基于复制算法,将活着的对象复制到to区域,拷贝过程中将对象顺序放置,这样就可以避免内存碎片化。因为要进行复制,所以要提前预留内存空间,有一定的浪费。另外,对于G1这种内存分拆为大量region的GC,GC需要维护region之间对象引用关系,需要很大的开销。

标记-清除算法:

首先进行标记工作,标识出需要回收的对象,然后进行清除。标记、清除的过程效率有限,并且会不可避免的出现碎片化问题,不适合特别大的堆。

标记-整理算法:

类似于标记-清除算法,但为避免内存碎片化,它会在清理过程中将对象移动,以确保移动后的对象占用连续的内存空间。

要回收哪些区域

在JVM内存模型中,有三个是不需要进行垃圾回收的:程序计数器、JVM栈、本地方法栈。因为它们的生命周期是和线程同步的,随着线程的销毁,它们占用的内存会自动释放,所以只有方法区和堆需要进行GC

方法区如何判断是否需要回收

方法区主要回收的内容有:废弃常量和无用的类。对于废弃常量也可通过引用的可达性来判断,但是对于无用的类则需要同时满足下面3个条件:
① 该类所有的实例都已经被回收,也就是Java堆中不存在该类的任何实例;
② 加载该类的ClassLoader已经被回收;
③ 该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。

GC是什么时候触发的(面试最常见的问题之一)

由于对象进行了分代处理,因此垃圾回收区域、时间也不一样。GC有两种类型:Minor GC和Full GC。
Minor GC
  一般情况下,当新对象生成,并且在Eden申请空间失败时,就会触发Minor GC,对Eden区域进行GC,清除非存活对象,并且把尚且存活的对象移动到Survivor区。然后整理Survivor的两个区。这种方式的GC是对年轻代的Eden区进行,不会影响到年老代。因为大部分对象都是从Eden区开始的,同时Eden区不会分配的很大,所以Eden区的GC会频繁进行。因而,一般在这里需要使用速度快、效率高的算法,使Eden去能尽快空闲出来。
Full GC
对整个堆进行整理,包括Young、Tenured和Perm。Full GC因为需要对整个堆进行回收,所以比Scavenge GC要慢,因此应该尽可能减少Full GC的次数。在对JVM调优的过程中,很大一部分工作就是对于Full GC的调节。有如下原因可能导致Full GC:
a) 年老代(Tenured)被写满;
b) 持久代(Perm)被写满;
c) System.gc()被显示调用;
d) 上一次GC之后Heap的各域分配策略动态变化;

最后来讲一下垃圾回收流程。

eden就相当于是使用空间,survivor就相当于是保留空间,通常情况下eden会比survivor大的多,因为eden和survivor都是属于新生代
1、新建的对象,大部分存储在Eden中
2、当Eden内存不够,就进行Minor GC释放掉不活跃对象;然后将部分活跃对象复制到Survivor中(如Survivor1),同时清空Eden区
3、当Eden区再次满了,将Survivor1中不能清空的对象存放到另一个Survivor中(如Survivor2),同时将Eden区中的不能清空的对象,复制到Survivor1,同时清空Eden区
4、重复多次(默认15次):Survivor中没有被清理的对象就会复制到老年区(Old)
5、当Old达到一定比例,则会触发Major GC释放老年代
6、当Old区满了,则触发一个一次完整的垃圾回收(Full GC)
7、如果内存还是不够,JVM会抛出内存不足,发生oom,内存泄漏。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值