JVM中的内存划分与垃圾回收算法

一、内存划分
下面这张图完美的展示了JVM的内存划分

阿斯达
可以看出,JVM将内存划分为堆区和非堆区,非堆区用来存储编译和保存的本地代码、虚拟机自己的静态数据、方法参数、局域变量等的引用以及方法执行顺序、本地方法的调用栈;而堆区则是存放创建的对象等。

下图所示是堆中内存分配示意图,创建一个对象,首先会在eden区域分配区域,如果内存不够,就会将年龄大的转移到Survivor区,当survivor区域存储不下,则会转移年老代的。对于一些静态变量不需要使用对象,直接调用的,则会被放入永生代。一般来说长期存活的对象最终会被存放到年老代,还有一种特殊情况也会被存放到年老代,就是创建大对象时,比如数据这种需要申请连续空间的,如果空间比较大的,则会直接进入年老代。
在这里插入图片描述
在回收过程中,有一个参数比较重要,就是对象的年龄,如果在一次垃圾回收过程中有使用该对象的,则将对象年龄加1,否则减1,当计数为0,则进行回收,如果年龄达到一定数字则进入老生代。总的来说内存分配机制主要体现在对象创建之后是否仍在使用,已经不使用的则回收,继续使用的则对其年龄进行更新,达到一定程度,转移到年老代。
二、垃圾回收算法
1.标记-清除算法
该算法先标记,后清除,将所有需要回收的算法进行标记,然后清除;这种算法的缺点是:效率比较低;标记清除后会出现大量不连续的内存碎片,这些碎片太多可能会使存储大对象会触发GC回收,造成内存浪费以及时间的消耗。

2.复制算法
复制算法将可用的内存分成两份,每次使用其中一块,当这块回收之后把未回收的复制到另一块内存中,然后把使用的清除。这种算法运行简单,解决了标记-清除算法的碎片问题,但是这种算法代价过高,需要将可用内存缩小一半,对象存活率较高时,需要持续的复制工作,效率比较低。

3.标记整理算法
标记整理算法是针对复制算法在对象存活率较高时持续复制导致效率较低的缺点进行改进的,该算法是在标记-清除算法基础上,不直接清理,而是使存活对象往一端游走,然后清除一端边界以外的内存,这样既可以避免不连续空间出现,还可以避免对象存活率较高时的持续复制。这种算法适合老生代。

4.分代收集算法
分代收集算法就是目前虚拟机使用的回收算法,它解决了标记整理不适用于老年代的问题,将内存分为各个年代,在不同年代使用不同的算法,从而使用最合适的算法,新生代存活率低,可以使用复制算法。而老年代对象存活率高,没有额外空间对它进行分配担保,所以使用标记整理算法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章