您的位置:首页 > 其它

JVM的组成、垃圾回收机制

2018-04-01 00:47 232 查看

面试准备之JVM的组成、垃圾回收机制

这是原链接,更具体的请查看原链接,这里简化了一些,也添加了一些自己的东西

https://www.cnblogs.com/wabi87547568/p/5282892.html

JVM分成了6个部分:JVM解释器(处理字段码的CPU)、指令系统、寄存器(快速地与JVM的解释器进行数据交换)、栈(为该代码中一个类的每一个方法创建一个栈框架)、存储区和碎片回收区(JVM 1.4.1版后产生了一种叫分代收集技术,简单来说就是利用对象在程序中生存的时间划分成代,以此为标准进行碎片回收。)

注:操作码和操作数:操作码和操作数,操作码决定要完成的操作,操作数指参加运算的数据及其所在的单元地址。

GC通过确定对象是否被活动对象引用来确定是否收集该对象。

触发GC(Garbage Collector)的条件

GC在优先级最低的线程中运行,一般在应用程序空闲即没有应用线程在运行时被调用。但下面的条件例外。

Java堆内存不足时,GC会被调用。当应用线程在运行,并在运行过程中创建新对象,若这时内存空间不足,JVM就会强制调用GC线程。若GC一次之后仍不能满足内存分配,JVM会再进行两次GC,(总共是三次GC)。若仍无法满足要求,则JVM将报“out

of memory”的错误,Java应用将停止。

对象在JVM堆区的状态

可触及状态:程序中还有变量引用,那么此对象为可触及状态

可复活状态:当程序中已经没有变量引用这个对象,那么此对象由可触及状态转为可复活状态。CG线程将在一定的时间准备调用此对象的finalize方法(finalize方法继承或重写子Object),finalize方法内的代码有可能将对象转为可触及状态,否则对象转化为不可触及状态。

不可触及状态:只有当对象处于不可触及状态时,GC线程才能回收此对象的内存。

常用垃圾收集器

标记-清除收集器 Mark-Sweep

tracing算法

基于tracing算法的垃圾收集也称为标记和清除(mark-and-sweep)垃圾收集器.

这是最基础的垃圾回收算法,之所以说它是最基础的是因为它最容易实现,思想也是最简单的。标记-清除算法分为两个阶段:标记阶段和清除阶段。标记阶段的任务是标记出所有需要被回收的对象,清除阶段就是回收被标记的对象所占用的空间。

复制收集器 Copying  

 为了解决Mark-Sweep算法的缺陷,Copying算法就被提了出来。它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用的内存空间一次清理掉,这样一来就不容易出现内存碎片的问题。

标记-压缩收集器 Mark-Compact

为了解决Copying算法的缺陷,充分利用内存空间,提出了Mark-Compact算法。该算法标记阶段和Mark-Sweep一样,但是在完成标记之后,它不是直接清理可回收对象,而是将存活对象都向一端移动,然后清理掉端边界以外的内存

分代收集器(面试常考)   Generational

分代收集算法是目前大部分JVM的垃圾收集器采用的算法。它的核心思想是根据对象存活的生命周期将内存划分为若干个不同的区域。一般情况下将堆区划分为老年代(Tenured

Generation)和新生代(Young

Generation),老年代的特点是每次垃圾收集时只有少量对象需要被回收(因为长生命周期的对象少),而新生代的特点是每次垃圾回收时都有大量的对象需要被回收(因为短生命周期的对象多),那么就可以根据不同代的特点采取最适合的收集算法。

目前大部分垃圾收集器对于新生代都采取Copying算法,因为新生代中每次垃圾回收都要回收大部分对象,也就是说需要复制的操作次数较少,但是实际中并不是按照1:1的比例来划分新生代的空间的,一般来说是将新生代划分为一块较大的Eden空间和两块较小的Survivor空间,每次使用Eden空间和其中的一块Survivor空间,当进行回收时,将Eden和Survivor中还存活的对象复制到另一块Survivor空间中,然后清理掉Eden和刚才使用过的Survivor空间。

而由于老年代的特点是每次回收都只回收少量对象,一般使用的是Mark-Compact算法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: