JVM系列(三)垃圾回收

什么对象需要被回收??

  没有被引用的对象要被回收。

怎么判定对象已经没有被引用???

1、引用计数算法。(因为循环引用问题,java没有使用这种方法)

2、可达性分析法。

主流实现。判定对象是否被引用。从GC ROOTS节点找引用链。

(对象的引用有分为:强引用、软引用、弱引用、虚引用。 先不管~)

根据区域划分垃圾回收

新生代的垃圾回收(minor gc)

当新生代满了,执行的垃圾回收就是minor gc。

  • 绝大部分新创建的对象在eden区。
  • 当eden区满了, Minor GC 就执行,而且所有的survivor区域里面的对象,丢到一个survivor里面。
  • 在一个时间中,必定其中一个survivor区是空的。
  • 好多轮minor GC后还是存在的对象,会被移到老生代。一般是有一个门限(threshold for the age of the young generation )

老生代的垃圾回收(major gc)

老生代满了就执行这个gc

 

perm只在full gc下执行垃圾回收(目前发现只有cms会回收p区?)

 

执行上述的垃圾回收,都会暂停jvm里面的所有应用!

minor gc是很快的,但是major gc很耗时。

 

 

full gc就是分别执行minor gc,major gc,还垃圾回收了p区。

垃圾回收算法

1、标记--清除算法(mark-sweep)

最基本、最早的垃圾回收算法。一般是不适用的。

比如说某个generation内存耗尽时触发。

步骤如下:

--stop the world。

--遍历所有gc roots。可达到的表示为存活。

--遍历heap中的对象,将没有标记为存活的清除。

缺点:慢,需要遍历;清理出来的空间不是连续的。

(参考:http://www.th7.cn/Program/java/201308/146907.shtml)

2、复制(copying)

常用的实现算法。

把一个区域中存活的复制到另外一个区域中。

比如说eden+一个survivor——>另外一个survivor。

也满了的话,丢到老生代。

缺点:对象存活率较高,就会变慢。

3、标记--整理(mark-compact)

老年代的实现方式。

--stop the world。

--遍历所有gc roots。可达到的表示为存活。

--所有存活的对象向一边移。

4、分代收集(generational collection)

当前的商用收集方法。

是2、3的综合体。根据对象特征, 使用2还是使用3。

垃圾收集器

无论哪一种垃圾收集器, 都会stop the world。只是停顿时间长短区别。

不同的垃圾收集器有不同的作用。

serial收集器:

最早的实现。

单线程。

用于新生代。

使用复制算法。

还在使用,运行在client模式下的虚拟机是不错的。

Parallel Scavenge:

多线程,用于新生代。

使用复制算法。

可以用于server模式。

不建议单CPU下使用。

ParNew收集器:

增强版Parallel Scavenge,可以与CMS配合使用。

Serial old:

单线程。

标记--清除算法。

用于老生代

Parallel Old:

多线程

标记-整理算法。

用于老生代

CMS:

多线程, 用于老生代。

两次stop the world。

cms一般是sweep(清除)操作,而不是。整理后空间是不连续的。

有一个阀值,空间不连续到一定程度后compact(整理)。或者进行full gc。

有一个参数设置,可以收集p区。

  • 初始标记(init mark):收集根引用,这是一个stop-the-world阶段。
  • 并发标记(concurrent mark):这个阶段可以和用户应用并发进行。遍历老年代的对象图,标记出活着的对象。
  • 并发预清理(concurrent preclean):这同样是一个并发的阶段。主要的用途也是用来标记,用来标记那些在前面标记之后,发生变化的引用。主要是为了缩短remark阶段的stop-the-world的时间。
  • 重新标记(remark):这是一个stop-the-world的操作。暂停各个应用,统计那些在发生变化的标记。
  • 并发清理(concurrent sweep):并发扫描整个老年代,回收一些在对象图中不可达对象所占用的空间。
  • 并发重置(concurrent reset):重置某些数据结果,以备下一个回收周期开始。

G1:

不区分新生代还是老生代的垃圾收集器。基于标记--整理。没有碎片。

  不同的垃圾回收器,作用在何处:

参考:

https://blogs.oracle.com/jonthecollector/entry/our_collectors

cms垃圾采集器:http://blog.griddynamics.com/2011/06/understanding-gc-pauses-in-jvm-hotspots_02.html

有道云笔记:http://note.youdao.com/share/?id=4e102baa9a3fa30230ff3837f6a9e79e&type=note

时间: 2024-10-27 11:29:18

JVM系列(三)垃圾回收的相关文章

【JVM】JVM系列之垃圾回收(二)

一.为什么需要垃圾回收 如果不进行垃圾回收,内存迟早都会被消耗空,因为我们在不断的分配内存空间而不进行回收.除非内存无限大,我们可以任性的分配而不回收,但是事实并非如此.所以,垃圾回收是必须的. 二.哪些内存需要进行垃圾回收 对于虚拟机中线程私有的区域,如程序计数器.虚拟机栈.本地方法栈都不需要进行垃圾回收,因为它们是自动进行的,随着线程的消亡而消亡,不需要我们去回收,比如栈的栈帧结构,当进入一个方法时,就会产生一个栈帧,栈帧大小也可以借助类信息确定,然后栈帧入栈,执行方法体,退出方法时,栈帧出

JVM系列之垃圾回收(二)

一.为什么需要垃圾回收 如果不进行垃圾回收,内存迟早都会被消耗空,因为我们在不断的分配内存空间而不进行回收.除非内存无限大,我们可以任性的分配而不回收,但是事实并非如此.所以,垃圾回收是必须的. 二.哪些内存需要进行垃圾回收 对于虚拟机中线程私有的区域,如程序计数器.虚拟机栈.本地方法栈都不需要进行垃圾回收,因为它们是自动进行的,随着线程的消亡而消亡,不需要我们去回收,比如栈的栈帧结构,当进入一个方法时,就会产生一个栈帧,栈帧大小也可以借助类信息确定,然后栈帧入栈,执行方法体,退出方法时,栈帧出

[转]JVM系列三:JVM参数设置、分析

[转]JVM系列三:JVM参数设置.分析 不管是YGC还是Full GC,GC过程中都会对导致程序运行中中断,正确的选择不同的GC策略,调整JVM.GC的参数,可以极大的减少由于GC工作,而导致的程序运行中断方面的问题,进而适当的提高Java程序的工作效率.但是调整GC是以个极为复杂的过程,由于各个程序具备不同的特点,如:web和GUI程序就有很大区别(Web可以适当的停顿,但GUI停顿是客户无法接受的),而且由于跑在各个机器上的配置不同(主要cup个数,内存不同),所以使用的GC种类也会不同(

Java性能优化之JVM GC(垃圾回收机制)

Java的性能优化,整理出一篇文章,供以后温故知新. JVM GC(垃圾回收机制) 在学习Java GC 之前,我们需要记住一个单词:stop-the-world .它会在任何一种GC算法中发生.stop-the-world 意味着JVM因为需要执行GC而停止了应用程序的执行.当stop-the-world 发生时,除GC所需的线程外,所有的线程都进入等待状态,直到GC任务完成.GC优化很多时候就是减少stop-the-world 的发生. JVM GC回收哪个区域内的垃圾? 需要注意的是,JV

JVM分代垃圾回收策略的基础概念

JVM分代垃圾回收策略的基础概念 由于不同对象的生命周期不一样,因此在JVM的垃圾回收策略中有分代这一策略.本文介绍了分代策略的目标,如何分代,以及垃圾回收的触发因素. 文章总结了JVM垃圾回收策略为什么要分代,如何分代,以及垃圾回收的触发因素. 为什么要分代 分代的垃圾回收策略,是基于这样一个事实:不同的对象的生命周期是不一样的.因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率. 在Java程序运行的过程中,会产生大量的对象,其中有些对象是与业务信息相关,比如Http请求中的S

【转载】Java性能优化之JVM GC(垃圾回收机制)

章来源:https://zhuanlan.zhihu.com/p/25539690 Java的性能优化,整理出一篇文章,供以后温故知新. JVM GC(垃圾回收机制) 在学习Java GC 之前,我们需要记住一个单词:stop-the-world .它会在任何一种GC算法中发生.stop-the-world 意味着JVM因为需要执行GC而停止了应用程序的执行.当stop-the-world 发生时,除GC所需的线程外,所有的线程都进入等待状态,直到GC任务完成.GC优化很多时候就是减少stop-

JVM常见的垃圾回收算法

JVM常见的垃圾回收算法 1.标记-清除算法 标记清除算法也是最基础的算法,就如同他的名字一样,标记清除算法的步骤分为两个步骤,首先标记出需要回收的所有对象,然后在完成标记之后统一清除掉所有被标记的对象,之所以说它是最基础的算法,是因为后续算法都是基于此算法,改进其缺点衍生出来的,标记清除算法有两个缺点,标记和清除这两个步骤都会有性能损耗,且效率低,其次是在完成对象的清除后会留下不连续的内存碎片,算法如下图: 2.复制算法 为了提高效率,我们又引入了复制算法,将现有可用的内存大小均分为二,每次只

JVM学习系列(二) 垃圾回收

如何判断对象是否可回收 引用计数法 1.概念:给对象中添加一个引用计数器,每当有一个地方引用他时,计数器的值+1,当引用失效的时候,计数器-1,任何时刻计数器为0的对象就是不可以在被使用的对象. 2.缺点:无法解决对象循环引用的问题(如下图) 可达性分析法 1.概念:垃圾回收根节点(GCRoot)向下搜索,搜索所走过的路径称为引用链,当一个对象对GCRoot没有任何的引用链时,代表当前对象不可用. 2.GCRoot包含的对象: 虚拟机栈(帧栈中的本地变量表)中的引用的对象 方法区类静态属性 所引

深入理解JAVA虚拟机之JVM性能篇---垃圾回收

一.基本垃圾回收算法 1. 按基本回收策略分 1) 引用计数(Reference Counting)  对象增加一个引用,即增加一个计数,删除一个引用则减少一个计数.垃圾回收时,只用收集计数为0的对象.此算法最致命的是无法处理循环引用的问题. 2)标记-清除(Mark-Sweep)  执行分两阶段.第一阶段从引用根节点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除. 缺点是此算法需要暂停整个应用,同时会产生内存碎片. 3)复制(Copying) 把内存空间划为两个相等的区域,每

JVM基础(5)-垃圾回收机制

一.对象引用的类型 Java 中的垃圾回收一般是在 Java 堆中进行,因为堆中几乎存放了 Java 中所有的对象实例.谈到 Java 堆中的垃圾回收,自然要谈到引用.在 JDK1.2 之前,Java 中的引用定义很很纯粹:如果 reference 类型的数据中存储的数值代表的是另外一块内存的起始地址,就称这块内存代表着一个引用.但在 JDK1.2 之后,Java 对引用的概念进行了扩充,将其分为强引用(Strong Reference).软引用(Soft Reference).弱引用(Weak