垃圾回收简介

Posted yuanfei1110111

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了垃圾回收简介相关的知识,希望对你有一定的参考价值。

GC是垃圾收集的意思,内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。Java程序员不用担心内存管理,因为垃圾收集器会自动进行管理。要请求垃圾收集,可以调用下面的方法之一:System.gc() 或Runtime.getRuntime().gc() ,但JVM可以屏蔽掉显示的垃圾回收调用。
  垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低优先级的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。在Java诞生初期,垃圾回收是Java最大的亮点之一,因为服务器端的编程需要有效的防止内存泄露问题,然而时过境迁,如今Java的垃圾回收机制已经成为被诟病的东西。移动智能终端用户通常觉得ios的系统比android系统有更好的用户体验,其中一个深层次的原因就在于Android系统中垃圾回收的不可预知性。
  补充:垃圾回收机制有很多种,包括:分代复制垃圾回收、标记垃圾回收、增量垃圾回收等方式。标准的Java进程既有栈又有堆。栈保存了原始型局部变量,堆保存了要创建的对象。Java平台对堆内存回收和再利用的基本算法被称为标记和清除,但是Java对其进行了改进,采用“分代式垃圾收集”。这种方法会跟Java对象的生命周期将堆内存划分为不同的区域,在垃圾收集过程中,可能会将对象移动到不同区域:
  - 伊甸园(Eden):这是对象最初诞生的区域,并且对大多数对象来说,这里是它们唯一存在过的区域。
  - 幸存者乐园(Survivor):从伊甸园幸存下来的对象会被挪到这里。
  - 终身颐养园(Tenured):这是足够老的幸存对象的归宿。年轻代收集(Minor-GC)过程是不会触及这个地方的。当年轻代收集不能把对象放进终身颐养园时,就会触发一次完全收集(Major-GC),这里可能还会牵扯到压缩,以便为大对象腾出足够的空间。
  与垃圾回收相关的JVM参数:
  -Xms / -Xmx — 堆的初始大小 / 堆的最大大小
  -Xmn — 堆中年轻代的大小
  -XX:-DisableExplicitGC — 让System.gc()不产生任何作用
  -XX:+PrintGCDetails — 打印GC的细节
  -XX:+PrintGCDateStamps — 打印GC操作的时间戳
  -XX:NewSize / XX:MaxNewSize — 设置新生代大小/新生代最大大小
  -XX:NewRatio — 可以设置老生代和新生代的比例
  -XX:PrintTenuringDistribution — 设置每次新生代GC后输出幸存者乐园中对象年龄的分布
  -XX:InitialTenuringThreshold / -XX:MaxTenuringThreshold:设置老年代阀值的初始值和最大值
  -XX:TargetSurvivorRatio:设置幸存区的目标使用率

常见的垃圾回收方式如下。

标记清除法:这是垃圾收集算法中最基础的,它的思想是标记哪些要被回收的对象,然后统一回收。这种方法很简单,但是效率不高,标记和清除的效率都很低;此外会产生大量不连续的内存碎片,从而导致以后程序在分配较大对象时由于没有充足的连续内存而提前触发一次 GC 操作。

复制算法:为了解决效率问题,复制算法将可用内存按容量划分为相等的两部分,然后每次只使用其中的一块,当一块内存用完后就将还存活的对象复制到第二块内存上,然后一次性清楚完第一块内存,再将第二块上的对象复制到第一块。但是这种方式内存的代价太高,每次基本上都要浪费一半的内存;于是将该算法进行了改进,内存区域不再是按照 1:1 去划分,而是将内存划分为 8:1:1 三部分,较大那份内存是 Eden 区,其余是两块较小的内存区叫 Survior 区,每次都会优先使用 Eden 区,若 Eden 区满则将对象复制到第二块内存区上,然后清除 Eden 区,如果此时存活的对象太多,以至于 Survivor 不够时,会将这些对象通过分配担保机制复制到老年代中。

标记整理法:这种方法主要是为了解决标记清除法产生大量内存碎片的问题;当对象存活率较高时,也解决了复制算法的效率问题。它的不同之处就是在清除对象的时候现将可回收对象移动到一端,然后清除掉端边界以外的对象,这样就不会产生内存碎片了。

分代收集法:现在的虚拟机垃圾收集大多采用这种方式,它根据对象的生存周期,将堆分为新生代和老年代。在新生代中,由于对象生存期短,每次回收都会有大量对象死去,那么这时就采用复制算法。老年代里的对象存活率较高,没有额外的空间进行分配担保,所以可以使用标记整理法或标记清除法。

























以上是关于垃圾回收简介的主要内容,如果未能解决你的问题,请参考以下文章

垃圾回收简介

V8 JavaScript引擎研究垃圾回收器的实现

第 16 期前沿实践:垃圾回收器是如何演进的?

Java垃圾回收机制(GC)详解

17_2_垃圾收集器_简介G1回收器:区域化分代式

Java GC(垃圾回收)机制知识总结