Java垃圾回收机制

简介:

JVM框架

Java虚拟机HotSpot的框架:

JVM主要组成部分:Class Loader(类加载器)、Runtime Data Area(运行时数据区)、执行引擎(Execution Engine)。

JVM垃圾回收简介

Step 1: Marking

 

GC算法在扫描存活对象时通常需要从Root节点开始,扫描所有存活对象的引用,构建出对象图。

Root:静态字段、方法参数、局部变量、CPU寄存器

Step 2: Normal Deletion

 

删除没有被引用的对象,释放空间。

Step 2a: Deletion with Compacting

删除垃圾并压缩存活的引用对象,有利于提高内存分配的效率。

Generational Garbage Collection(分代垃圾回收)

HotSpot堆结构:

 

Young Generation:从eden区分配新对象,eden区满后,发生一次minor garbage collection,把eden区和一个survivor区中存活的对象移动到另一个survivor区中,存活的对象age加1,当存活的对象age达到一个阈值时晋升到Old Generation。

Old Generation:保存存活长久对象的地方,Old Generation满后会发生major garbage collection(full garbage collection)。

Stop the World Event:minor garbage collection和major garbage collection都是Stop the World Event,即垃圾回收的时候会暂停程序中线程的执行。

Permanent generation:保存JVM中用于描述类和方法的元数据信息。

整个GC的流程总结图:

 

GC分代的基本假设是:绝大部分对象的生命周期都非常短暂,存活时间短。

分配小对象的开销负担小,不要吝啬去创建。

GC最喜欢这种小而短命的对象。

让对象的生命周期尽可能短,例如在方法体内创建,使其能尽快地在YoungGC中被回收,不会晋升(romote)到年老代(Old Generation)。

对象分配的优化:尽量避免大对象的分配,当对象大到Eden Generation放不下时,JVM只能尝试去Old Generation分配,这种情况需要尽可能避免,因为一旦在Old Generation分配,这个对象就只能被Old Generation的GC或是FullGC回收了。

不可变对象可以减少GC的压力:Hotspot JVM为了提高YoungGC的性能,避免每次YoungGC都扫描Old Generation中的对象引用,采用了卡表(Card Table) 的方式。简单来说,当Old Generation中的对象发生对Young Generation中的对象产生新的引用关系或释放引用时,都会在卡表中响应的标记上标记为脏(dirty),而YoungGC时,只需要扫描这些dirty的项就可以了。可变对象对其它对象的引用关系可能会频繁变化,并且有可能在运行过程中持有越来越多的引用,特别是容器。这些都会导致对应的卡表项被频繁标记为dirty。而不可变对象的引用关系非常稳定,在扫描卡表时就不会扫到它们对应的项了。

指定容器初始化大小可以减少GC的压力:每次容器扩容分配更大的空间,可能会增加GC的次数。

各类引用:java.lang.ref.Reference有几个子类,用于处理和GC相关的引用。JVM的引用类型简单来说有几种:

Strong Reference,最常见的引用。

Weak Reference,当没有指向它的强引用时会被GC回收。

Soft Reference,只当临近OOM时才会被GC回收。

Phantom Reference,主要用于识别对象被GC的时机,通常用于做一些清理工作。

Garbage Collector(垃圾收集器)

JVM中会在以下情况触发回收:对象没有被引用,作用域发生未捕捉异常,程序正常执行完毕,程序执行了System.exit(),程序发生意外终止。

JVM中标记垃圾使用的算法是一种根搜索算法。简单的说,就是从一个叫GC Roots的对象开始,向下搜索,如果一个对象不能达到GC Roots对象的时候,说明它可以被回收了。这种算法比一种叫做引用计数法的垃圾标记算法要好,因为它避免了当两个对象啊互相引用时无法被回收的现象。

JVM中对于被标记为垃圾的对象进行回收时又分为了一下3种算法:

1.标记清除算法,该算法是从根集合扫描整个空间,标记存活的对象,然后在扫描整个空间对没有被标记的对象进行回收,这种算法在存活对象较多时比较高效,但会产生内存碎片。

2.复制算法,该算法是从根集合扫描,并将存活的对象复制到新的空间,这种算法在存活对象少时比较高效。

3.标记整理算法,标记整理算法和标记清除算法一样都会扫描并标记存活对象,在回收未标记对象的同时会整理被标记的对象,解决了内存碎片的问题。

HotSpot 1.6版使用的垃圾收集器如下图(图中两个收集器之间有连线,说明它们可以配合使用):

1.Serial GC

从名字上看,串行GC意味着是一种单线程的,所以它要求收集的时候所有的线程暂停。这对于高性能的应用是不合理的,所以串行GC一般用于Client模式的JVM中。

2.ParNew GC

是在SerialGC的基础上,增加了多线程机制。但是如果机器是单CPU的,这种收集器是比SerialGC效率低的。

3.Parrallel Scavenge GC

这种收集器又叫吞吐量优先收集器,而吞吐量=程序运行时间/(JVM执行回收的时间+程序运行时间),假设程序运行了100分钟,JVM的垃圾回收占用1分钟,那么吞吐量就是99%。Parallel Scavenge GC由于可以提供比较不错的吞吐量,所以被作为了server模式JVM的默认配置。

4.ParallelOld

是老生代并行收集器的一种,使用了标记整理算法,是JDK1.6中引进的,在之前老生代只能使用串行回收收集器。

5.Serial Old

是老生代client模式下的默认收集器,单线程执行,同时也作为CMS收集器失败后的备用收集器。

6.CMS(Concurrent Mark Sweep)

又称响应时间优先回收器,使用标记清除算法,同时它又是一个使用多线程并发回收的垃圾收集器。他的回收线程数为(CPU核心数+3)/4,所以当CPU核心数为2时比较高效些。CMS分为4个过程:初始标记、并发标记、重新标记、并发清除和并发重置。其中初始标记和重新标记是独占系统资源的,而并发标记、并发清除和并发重置是可以和用户线程一起执行的。因此,从整体上来说,CMS 收集不是独占式的,它可以在应用程序运行过程中进行垃圾回收。

7.Garbage First(G1)

比较特殊的是G1回收器既可以回收Young Generation,也可以回收Tenured Generation。它是在JDK6的某个版本中才引入的,性能比较高,同时注意了吞吐量和响应时间。与CMS收集器相比,G1收集器是基于标记-压缩算法的。因此,它不会产生空间碎片,也没有必要在收集完成后,进行一次独占式的碎片整理工作。

对于垃圾收集器的组合使用可以通过下表中的参数指定:

 

 

参考:

http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

http://coolshell.cn/articles/11541.html

http://www.ibm.com/developerworks/cn/java/j-lo-JVMGarbageCollection/index.html

http://www.importnew.com/16388.html

 

作者: 阿凡卢
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
http://www.cnblogs.com/luxiaoxun/p/4631575.html
相关文章
|
1月前
|
JavaScript 前端开发 算法
Java Script 中的垃圾回收机制有哪些缺点
Java Script 中的垃圾回收机制有哪些缺点
13 0
|
1月前
|
监控 算法 Java
深入理解Java中的垃圾回收机制
【2月更文挑战第13天】 本文旨在深入剖析Java中的核心机制之一——垃圾回收(Garbage Collection, GC)。与传统的摘要不同,我们不会概述全文内容,而是直接点明文章将探讨的重点问题:如何合理利用垃圾回收机制优化Java应用性能。通过分析不同垃圾回收器的工作原理与特点,本文将指导开发者识别和处理内存泄漏,选择合适的垃圾回收策略,以及评估垃圾回收行为对应用性能的实际影响。
24 1
|
6月前
|
监控 算法 Java
百度搜索:蓝易云【Java垃圾回收机制详解及性能优化详解。】
Java的垃圾回收机制自动管理内存,使开发人员不必手动处理内存释放的问题。通过了解垃圾回收算法、垃圾回收器的选择和性能优化的技巧,可以提高应用程序的性能和响应速度。但在进行性能优化时,需要根据具体的应用场景和需求进行评估和调整,以找到最佳的配置和优化策略。
135 0
|
1月前
|
算法 Java 程序员
深入理解Java中的垃圾回收机制
【2月更文挑战第20天】在Java中,垃圾回收(Garbage Collection, GC)是一个自动的内存管理过程,负责识别并回收那些不再被使用的对象所占用的内存。这一机制极大地简化了程序的内存管理,减少了程序员因手动管理内存而可能引入的错误。然而,为了编写出更高效且对系统资源利用更加合理的Java应用程序,开发者需要对垃圾回收器的工作原理有深入的理解。本文将探讨Java垃圾回收的基本概念、常见的垃圾回收算法以及JVM中垃圾回收器的实际运作方式。
|
2月前
|
算法 Java 程序员
深入理解Java垃圾回收机制
【2月更文挑战第8天】在Java中,垃圾回收机制是自动化的,这意味着程序员不必手动管理内存。然而,了解垃圾回收机制是非常重要的,因为它可以帮助我们优化代码以及避免一些常见的性能问题。
20 3
|
2月前
|
算法 Java 程序员
Java的垃圾回收机制及其优化方法
【2月更文挑战第7天】垃圾回收是Java语言中一项重要的特性,它可以自动管理内存资源,避免了手动释放内存的繁琐过程。本文将介绍Java的垃圾回收机制、垃圾回收算法以及优化方法,帮助读者更好地理解和应用Java的垃圾回收技术。
|
2月前
|
监控 算法 Java
Java中的垃圾回收机制详解
Java中的垃圾回收机制详解
|
7月前
|
算法 Java 程序员
JAVA垃圾回收机制
JAVA垃圾回收机制
36 0
JAVA垃圾回收机制
|
8月前
|
算法 Java
第一季:16JVM垃圾回收机制【Java面试题】
第一季:16JVM垃圾回收机制【Java面试题】
53 0
|
3月前
|
存储 监控 算法
Java垃圾回收机制详解和调优
Java垃圾回收机制详解和调优

热门文章

最新文章