美文网首页Java子弹
JVM内存分代模型(垃圾回收)

JVM内存分代模型(垃圾回收)

作者: salix_ | 来源:发表于2020-03-20 13:17 被阅读0次

感觉网上的资料是真的少,这个也是在听了马士兵老师的课之后又结合博客,深入理解JVM三,有了总结的路线。
一:垃圾回收针对堆区和方法区
二:怎样找到垃圾?
三:介绍新生代、老年代的模型(是部分垃圾回收器使用的模型)
四:清除垃圾算法?
五: Stop The World

一:垃圾回收针对堆区和方法区

hotspot在1.8之前叫永久代,1.8以及以后叫元数据空间。
hotspot1.8和和之前的变化:
1)移除了永久代(PermGen),替换为元空间(Metaspace);
2)永久代中的 class metadata 转移到了 native memory(本地内存,而不是虚拟机);
3)永久代中的 interned Strings 和 class static variables 转移到了 Java heap;(1.7就已经移除了)
4)永久代参数 (PermSize MaxPermSize) -> 元空间参数(MetaspaceSize MaxMetaspaceSize)

引用自《深入理解JVM三》:考虑到HotSpot未来的发展, 在JDK 6的时候HotSpot开发团队就有放弃永久代, 逐步改为采用本地内存(Native Memory) 来实现方法区的计划了[1], 到了JDK 7的HotSpot, 已经把原本放在永久代的字符串常量池、 静态变量等移出, 而到了JDK 8, 终于完全废弃了永久代的概念, 改用与JRockit、 J9一样在本地内存中实现的元空间(Metaspace) 来代替, 把JDK 7中永久代还剩余的内容(主要是类型信息) 全部移到元空间中。

二:怎样找到垃圾?

1.引用记数

给每个对象打上标记,被引用一次就cnt++,如果某个对象没有引用,cnt=0,那就可以清除,但是解决不了有向环类的相互引用。


2.Root Searching(根可达算法)
  1. 算法:标记根,从根开始搜索,根能到达的都不是垃圾,剩下的全是垃圾。
  2. 哪些是根:JVM stack(虚拟机栈栈帧里的引用对象)、方法区中类静态属性引用的变量、JNI指针指向的对象(就是Native方法)、虚拟机内部引用像NullPointerException和类加载器、Synchronized持有的对象。

三:介绍新生代、老年代的模型(是部分垃圾回收器使用的模型)

1.新生代、老年代介绍

  1. 垃圾回收区分为新生代、老年代。新生代又分为eden区,两个survivor。eden是干啥的?为啥要两个survivor?
  2. 注意图中默认内存大小的比例。
  3. 刚new的对象放在哪
    new一个对象默认是在eden区分配,如果对象比较大,eden放不下,直接放到老年代。
  4. 年轻代回收过程
    HotSpot虚拟机使用的是Copy算法,就是第一次进行YGC(年轻代垃圾回收,YGC不包含老年代)的时候。YGC首先把 eden该回收的回收,不该回收的放在survivor0区,age++。把eden清空,这样做可以减少eden区的空间碎片,并且效率比较高。
    survivor0的放到survivor1,survivor1的放到survivor0,都age++。如果age>cnt,那就把他放到老年代。(说明这个玩意儿用了好久,之后我们不要轻易的回收它。cnt不同的垃圾回收器是不一样的)
    这几个过程中,只要有放不下(内存)的都直接搁到老年代
  5. 老年代满了
    就进行一次Full GC,Full GC包含YGC。
    MinorGC=YGC MajorGC=FGC

2.JDK1.8当前默认垃圾回收器

是Parallel Scavenge(用于新生代的回收),Parallel Old(用于老年代的回收)。简称PSPO。没错是两个垃圾回收器!在JDK12不是开始收费了嘛,垃圾回收器换成了ZGC,不再用两个垃圾回收器,当然收费也贼高。ZGC就没有了新生代、老年代的概念。

四:垃圾清理算法

  • Mark-Sweep(标记清除)
  • Copying
  • Mark-Compact(标记整理)
1. Mark-Sweep(标记清除)

该回收的就标记,不回收的就不管,这样做算法容易实现,复杂度也可以,但是会产生大量的碎片。

2.Cpoying算法

把空间分成两部分,一半永远都不使用,回收的时候,把回收的区域所有有用的对象都放到另一块干净的区域。然后擦除所有刚被回收的区域。这样做的好处是算法复杂度都可,但是浪费了大量的空间。


3.Mark-Compact(标记整理)

和标记清除的方法不一样,标记整理是把未回收对象集中起来放到一起。这样做有点耗时间。


五:Stop The World

很多人都遇到过,游戏每天半夜都要维护。还有12306每晚深夜都不能买票,这很可能就是(我可没说是,也是听来的例子)STW现象。
对于分代回收器像我们前面提到的Parallel Scavenge、Parallel Old,GC线程在进行工作的时候,所有!是所有其他线程全部停止,等着GC线程回收完毕才能继续运行,这就是STW。像ZGC(不是分代回收器),它没有STW现象。

相关文章

网友评论

    本文标题:JVM内存分代模型(垃圾回收)

    本文链接:https://www.haomeiwen.com/subject/bcrkyhtx.html