03 | JVM-GC概念

为何要垃圾回收

随着程序的运行,内存中存在的实例对象、变量等信息占据的内存越来越多,如果不及时进行垃圾回收,必然会带来程序性能的下降,甚至会因为可用内存不足造成一些不必要的系统异常。

那些要垃圾回收

根据之前的JVM内存管理中知道,内存主要是,堆,栈,方法区,程序计数器,本地方法栈,而栈,方法区,程序计数器的声明周期是随着线程的结束,内存自动释放的,所以垃圾回收主要是针对方法区

何时要垃圾回收

简而言之就是对象在内存中“没用了”,这需要来及回收释放内存,但是如何判断对象没有用处则比较复杂,JVM定义了强、软、若、虚四种引用类型来定义对象,不同的引用类型的对象,在GC的时候有不同的处理方式

  • 强引用(Strong Reference).就是为刚被new出来的对象所加的引用,它的特点就是,永远不会被回收。

  • 软引用(Soft Reference).JVM内存并不紧张,这类对象可以不被回收,如缓存对象

  • 弱引用(Weak Reference).弱引用的对象就是一定需要进行垃圾回收的,不管内存是否紧张

  • 虚引用(Phantom Reference).JVM完全不会在乎虚引用,其唯一作用就是做一些跟踪记录,辅助finalize函数的使用

垃圾回收方式

03 | JVM-GC概念_第1张图片

内存主要被分为三块,新生代老年代持久代。三代的特点不同,造就了他们所用的GC算法不同

  • 新生代:用于存储新new出来的对象,一般垃圾回收回收这里,当垃圾回收后没有被回收的对象会放到Survivor Spaces中(为复制算法提供了专门的from-to区域)
  • 老年代:用于存储,经过几次垃圾回收没被回收的对象(如缓存对象)
  • 永久代:一般存储方法区中的类信息,Class在被 Load的时候被放入PermGen space区域. 它和和存放Instance的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误

Scavenge GC

一般情况下,当新对象生成,并且在Eden申请空间失败时,就会触发Scavenge GC,对Eden区域进行GC,清除非存活对象,并且把尚且存活的对象移动到Survivor区。然后整理Survivor的两个区。这种方式的GC是对年轻代的Eden区进行,不会影响到年老代。因为大部分对象都是从Eden区开始的,同时Eden区不会分配的很大,所以Eden区的GC会频繁进行。因而,一般在这里需要使用速度快、效率高的算法,使Eden去能尽快空闲出来。

Full GC

对整个堆进行整理,包括Young、Tenured和Perm。Full GC因为需要对整个对进行回收,所以比Scavenge GC要慢,因此应该尽可能减少Full GC的次数。在对JVM调优的过程中,很大一部分工作就是对于FullGC的调节。有如下原因可能导致Full GC:
· 年老代(Tenured)被写满
· 持久代(Perm)被写满
· System.gc()被显示调用
·上一次GC之后Heap的各域分配策略动态变化

你可能感兴趣的:(03 | JVM-GC概念)