最近整理GC相关原理,发现各种文章都太乱,于是整理一份自己看得懂,不废话,具体如下。
GC主要用于管理JVM的堆区,所以先来介绍一下JVM的内存分配。
1、程序计数器(Program Conuter Register)
程序计数器是一块较小的内存空间,它是当前线程执行字节码的行号指示器,字节码解释工作器就是通过改变这个计数器的值来选取下一条需要执行的指令。它是线程私有的内存,也是唯一一个没有OOM异常的区域。
2、Java虚拟机栈区(Java Virtual Machine Stacks)
也就是通常所说的栈区,它描述的是Java方法执行的内存模型,每个方法被执行的时候都创建一个栈帧(Stack Frame),用于存储局部变量表、操作数栈、动态链接、方法出口等。每个方法被调用到完成,相当于一个栈帧在虚拟机栈中从入栈到出栈的过程。此区域也是线程私有的内存,可能抛出两种异常:如果线程请求的栈深度大于虚拟机允许的深度将抛出StackOverflowError;如果虚拟机栈可以动态的扩展,扩展到无法动态的申请到足够的内存时会抛出OOM异常。
3、本地方法栈(Native Method Stacks)
本地方法栈与虚拟机栈发挥的作用非常相似,区别就是虚拟机栈为虚拟机执行Java方法,本地方法栈则是为虚拟机使用到的Native方法服务。
4、堆区(Heap)
所有对象实例和数组都在堆区上分配,堆区是GC主要管理的区域。堆区还可以细分为新生代、老年代,新生代还分为一个Eden区和两个Survivor区。此块内存为所有线程共享区域,当堆中没有足够内存完成实例分配时会抛出OOM异常。
5、方法区(Method Area)
方法区也是所有线程共享区,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。GC在这个区域很少出现,这个区域内存回收的目标主要是对常量池的回收和类型的卸载,回收的内存比较少,所以也有称这个区域为永久代(Permanent Generation)的。当方法区无法满足内存分配时抛出OOM异常。
6、运行时常量池(Runtime Constant Pool)
运行时常量池是方法区的一部分,用于存放编译期生成的各种字面量和符号引用。
针对GC的原理机制,主要搞清楚下面三个问题。
1、什么时候回收?
2、哪些需要回收?
3、怎么回收?
1、什么时候回收?
上面提到GC主要管理的是堆区,堆区主要分为新生代和老年代。大概解释一下这两个区域。
新生代:分为一个Eden和两个Survivor区。新new的对象都放在这里,很快消亡。
老年代:新new的大对象直接丢到这里(为了避免在Eden区和两个Survivor区发生大量的内存拷贝),其余就是在新生代多次回收没被干掉过来变成老家伙的对象了。
①对象优先分配到新生代的Eden区,当不够空间的时候进行一次Minor GC,清理频率很高。
②Full GC发生在老年代,当不够空间的时候进行一次Full GC,伴随着也会进行一次Minor GC。
③进行Minor GC时,会判断每次变成晋升到老年代的对象平均值是否大于老年代剩余空间,如果大于,则进行一次Full GC,如果小于就会去判断HandlePromotionFailure设置是否允许担保失败,如果允许,则进行Minor GC,不允许则改为Full GC。
2、哪些需要回收?
为了下面内容更好理解,首先来了解一下finalize方法。
什么是finalize()方法?
每次进行GC之前系统都会调用一次finalize()方法,用以清理所有活动并且释放资源。
什么时候调用finalize()方法?
1、GC调用之前,例如运行System.gc();(调用System.gc()只是建议JVM去执行,是否执行还得JVM去判断)
2、程序退出时,每个对象都会调用finalzie
3、显式调用finalize
--------------------------------------------------------------------------------------------------------------------------------
引用根搜索算法(GC ROOT Tracing),当一个对象没有任何引用连接的时候,则说明对象不可达,即对象不可用,这个时候就需要进行GC清理。
判断对象是否可达的依据是有没必要执行finalize()方法。如果finalize()方法没有被覆盖或者已经被系统调用过一次了(每个对象生命周期内只能调用一次),则被不可达,需要进行GC清理,否则进行自救,恢复引用连接。
--------------------------------------------------------------------------------------------------------------------------------
3、怎么回收?
不同区域回收算法不同。
新生代:停止-复制。
老年代:标记-清理、标记-整理。
新生代:新生代分为一个Eden区、两个Survivor区(Survivor0、Survivor1)。回收时先把Eden存活对象复制到Survivor0区,清空Eden区,当Survivor0区满了以后,把Eden和Survivor0区的存活对象复制到Survivor1区,清空Eden区和Survivor0区,之后交换Survivor0和Survivor1区,保持Survivor1区是空的,如此往复。
老年代:这两个没什么说的,字面理解。
相关推荐
java垃圾回收(gc)机制详解
Java垃圾回收机制详解!! GC详解!!
哪些内存需要回收是垃圾回收机制第一个要考虑的问题,所谓“要回收的垃圾”无非就是那些不可能再被任何途径使用的对象。
说起垃圾收集(Garbage Collection,GC),大部分人都把这项技术当做Java语言的伴生产物。经过半个世纪的发展,内存的动态分配与内存回收技术已经相当成熟,一切看起来都进入了“自动化”时代,那为什么我们还要去...
主要介绍了Java GC 机制与内存分配策略详解的相关资料,需要的朋友可以参考下
Java的垃圾回收机制详解和调优大全
gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存。java语言并不要求jvm有gc,也没有规定gc如何工作。不过常用的jvm都有gc,而且大多数gc都使用类似的算法管理内存和执行收集操作。
jvm详解高清pdf版,本文详细讲解了 JVM(Java Virtual Machine)的方方面面,首先由 java 的特性来描绘 JVM 的大致应用,再细细阐述了 JVM 的原理及内存管理机制和调优.最后讲述了与 JVM 密切相 关的 Java GC 机制.
Java虚拟机详解04----GC算法和种类【重要】,有助于更深入理解记忆,文字配图片,10分钟让你记住gc工作机制。
JVM的垃圾回收机制详解和调优,gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存。java语言并不要求jvm有gc,也没有规定gc如何工作。不过常用的jvm都有gc,而且大多数gc都使用类似的算法管理内存和...
本文档详细讲解了JVM(Java Visual Mathine)的方方面面,首先由java的特性来描绘JVM的大致应用,再详细阐释了 JVM 的原理及内存管理机制和调优,讲述了与JVM密切相关的 Java GC 机制,最后对 JVM 调优进行了总结。...
本文详细讲解了JVM(Java Virtual Machine)的...最后讲述了与JVM密切相关的Java GC机制. 本文内容大多来自网络,但内容十分丰富,是学习JVM的好资料. 后面会再针对JVM的两大职责class loader和 execution engine进行讲解
本文详细讲解了JVM(Java Virtual Machine)的方方面面,首先由java的特性来描绘JVM的大致应用,再细细阐述了JVM的原理及内存管理机制和调优.最后讲述了与JVM密切相关的Java GC机制.
本文详细讲解了JVM(Java Virtual Machine)的方方面面,首先由java的特性来描绘JVM的大致应用,再细细阐述了JVM的原理及内存管理机制和调优.最后讲述了与JVM密切相关的Java GC机制
本文详细讲解了JVM(Java Virtual Machine)的方方面面,首先由java的特性来描绘JVM的大致应用,再细细阐述了JVM的原理及内存管理机制和调优.最后讲述了与JVM密切相关的Java GC机制.
有了它,你将学到这些:java虚拟机的生命周期,JVM的体系结构,各部分详解,GC机制等
主要介绍了Java的堆内存与栈内存的存储机制,包括JVM的内存优化和GC等相关方面内容,需要的朋友可以参考下
谷咕咕最近在准备面试,本来想多看看堆和栈的关系,看看发现又设计到gc(Garbage Collection)垃圾回收机制,发现盲区太多了,就去粗略的学习了一下jvm(java虚拟机),发现之前只会写程序,底层的东西真是太丰富了...
* 在垃圾回收章节,不仅会介绍垃圾回收算法、分代垃圾回收机制,还会重点介绍 G1 垃圾回收器,辨析 Full GC 发生条件,jdk8以来对垃圾回收的优化,以及垃圾回收的调优法则。 * 在字节码与类加载技术章节,会从一个 ...