每一个使用 Java 的开发者都知道 Java 字节码是在 JRE 中运行。 JVM 则是 JRE 中的核心组成部分,承担分析和执行 Java 字节码的工做,而 Java 程序员一般并不须要深刻了解 JVM 运行状况就能够开发出大型应用和类库。尽管如此,若是你对 JVM 有足够了解,就会对 Java 有更好的掌握,而且能解决一些看起来简单但又还没有解决的问题。php
首先,咱们来看一下 JVM 不得不知道的体系结构,在编译完以后的 class 文件装载到类装载器的运行时数据区,运行时数据区分为五大块,分别是方法区,堆, Java 栈,本地方法栈,程序计数器。Java栈,本地方法栈,程序计数器存储本地方法接口,方法区和堆则存储执行引擎,也是 GC 的做用区域。 程序员
JDK1.8以前,内存管理机制采用分代的策略:分为新生代,老年代,永久代(JDK1.7及之前)。 面试
大体分为 Eden 区和 Survivor 区, Survivor 区又分为大小相同的两部分: s0 ( FromSpace ) 和 s1 ( ToSpace )。新建的对象都是重新生代分配内存, Eden 区不足的时候,会把存活的对象转移到 Survivor 区。当新生代进行垃圾回收时会触发 Minor GC 。通常在Eden区分配对象,使用 TLAB( Thread Local Allocation Buffer ) 进行优化,在保存80%~90%生命周期较短的对象,GC频率高,采用效率较高的复制算法。算法
新生代的三个分区默认比例为 8:1:1 ,JVM中规定 98% 的对象要在新生代被回收,而 s0 及 s1 只是做为暂存区,每次GC的触发以后必须保证其中一个区是空的,随后两个区互换位置,及 s0 -> s1 (from -> to),s1 -> s0 (to -> from),保证绝大部分对象在此被回收。缓存
旧生代用于存放新生代屡次回收依然存活的对象,如缓存对象。当旧生代满了的时候就须要对旧生代进行回收,旧生代的垃圾回收称做 Major GC。新建的对象也有可能直接在旧生代中分配,取决于具体GC的实现。GC频率相对较低,标记,清理,压缩算法的各类结合和优化。架构
对象经历了屡次 Major GC 仍然没有被回收即进入永久代,仅 JDK1.7 及以前的版本拥有。学习
咱们首先来看一下哪些是GC的目标,GC中使用的回收检测算法有两种,目前虚拟机基本上都是用可达性算法:优化
每一个对象有一个引用计数器,当对象被引用一次则计数器加1,当对象引用失效一次则计数器减1,对于计数器为0的对象意味着是垃圾对象,能够被GC回收。 cdn
从GC Roots做为起点开始搜索,那么整个连通图中的对象便都是活对象,对于GC Roots没法到达的对象便成了垃圾回收的对象,随时可被GC回收。 视频
从根集合开始扫描,对存活的对象进行标记。
扫描整个内存空间,回收未被标记的对象,使用free-list记录可回收区域。
与标记-清除同样
再次扫描,并往一段滑动存活对象
有问题?能够给我留言或私聊 有收获?那就顺手点个赞呗~
固然,也能够到个人公众号下「6曦轩」,
回复“学习”,便可收到一份 【Java工程师进阶架构师的视频教程】~
回复“面试”,能够收到一套 【本人呕心沥血整理的Java面试题目】(部分目录以下)