透视JVM之垃圾回收

JVM是JAVA世界的核心,了解它有助于我们更好调试,调优和开发程序,最近散仙在看JAVA特种兵一书,看完觉得,作者写的内容还是挺不错,大家感兴趣的,也可以购买本温故而知新下。

在JVM中,我们经常提到的就是堆了,堆确实很重要,其实,除了堆之外,还有几个重要的模块,看下图:

大多数情况下,我们并不需要关心JVM的底层,但是如果了解它的话,对于我们系统调优是非常有用的,在这里面了解JVM的GC原理,是非常重要的一块知识。我们都知道对于一个大型网站,如果JVM频繁发生FULL GC,那么将会是致命的危险,不仅仅会造成网站响应迟钝,更严重的时候会导致系统崩溃,这对用户体验来讲,都是我们不愿意看到的。

在JVM里的内存空间,从大的层面划分,主要有新生代空间(Young)和老年代空间(Old),其中Young空间,又被分为2个部分和3个板块,分别是1个Egen区,和2个Survivor区,看下图:

OK,下面来具体看下,每部分都是干啥的 
(1)Eden区域是用来存放使用new或者newInstance等方式创建的对象,默认都是存放在Eden区,除非这个对象太大,或者超过了设定的阈值-XX:PretenureSizeThresold,这样的对象会被直接分配到Old区域。

(2)2个Survivor(幸存)区,一般称S0,S1,理论上他们是一样大的,解释一下,他们是如何工作的: 
在不断创建对象的过程中,Eden区会满,这时候会开始做Young G也叫Minor GC,而Young空间的第一次GC就是找出Eden区中,幸存活着的对象,然后将这些对象,放到S0,或S1区中的其中一个, 假设第一次选择了S0,它会逐步将活着的对象拷贝到S0区域,但是如果S0区域满了,剩下活着的对象只能放old区域了,接下来要做的是,将Eden区域清空,此时时候S1区域也是空的。

当第二次Eden区域满的时候,就将Eden区域中活着的对象+S0区域中活着的对象,迁移到S1中,如果S1放不下,就会将剩下的部门,放到Old区域中,只是这次对象来源区域增加了S0,最后会将Eden区+S0区域,清空

第三次和第四次依次类推,始终保证S0和S1有一个是空的,用来存储临时对象,用于交换空间的目的,反反复复多次没有被淘汰的对象,将会放入old区域中,默认是15次。具体的交换过程就和上图中的信息相似。

问题一:怎么定义活着的对象? 
从根引用开始,对象的内部属性可能也是引用,只要能级联到的都被认为是活着的对象

问题二:什么是根? 
本地变量引用,操作数栈引用,PC寄存器,本地方法栈引用等这些都是根。

问题三:对象进入Old区域有什么坏处? 
old区域一般称为老年代,老年代与新生代不一样,年轻代,我们可以认为存活下来的对象很少,而老年代则相反,存活下来的对象很多,所以JVM的堆内存,才是我们通常关注的主战场,因为这里面活着的对象非常多,所以发生一次FULL GC,来找出来所有存活的对象是非常耗时的,因此,我们应该尽量避免FULL GC的发生。

问题四:S0和S1一般多大,靠什么参数来控制,有什么变化?

一般来说很小,我们大概知道它与Young差不多相差一倍的比例,设置的的参数主要有两个: 
-XX:SurvivorRatio=8 
-XX:InitialSurvivorRatio=8

第一个参数是Eden和Survivor区域比重,注意是一个Survivor的的大小,如果将其设置为8,则说明Eden区是一个Survivor区的8倍,换句话说S0或S1空间是整个Young空间的1/10,剩余的80%由Eden区域来使用。

第二个参数是Young/S0的比值,当其设置为8时,表示s0或s1占整个Young空间的12.5%。

问题五;一个对象每次Minor Gc时,活着的对象都会在s0和s1区域转移,经过经过Minor GC多少次后,会进入Old区域呢?

默认是15次,参数设置-XX:MaxTenuringThreshold=15,计数器会在对象的头部记录它交换的次数

问题六:为什么发生FULL GC会带来很大的危害?

在发生FULL GC的时候,意味着JVM会安全的暂停所有正在执行的线程(Stop The World),来回收内存空间,在这个时间段内,所有除了回收垃圾的线程外,其他有关JAVA的程序,代码都会静止,反映到系统上,就会出现系统响应大幅度变慢,卡机等状态。

举个通俗易懂点的例子,就是在一个房间里,如果有一个人,不停的扔垃圾,然后有一个清洁工不停扫垃圾,这时候,我们的系统是OK的,因为基本不会出现垃圾堆满房间的情景,而且因为清洁工可以对付过来,假设现在有10个人不停扔垃圾,那么就房间就会很快被堆满,这时候清洁工,由于工作不过来了,大声吼一声,你们都暂停3分钟,别再扔了,我先把这个房间打扫完,你们才可以扔。 
在这个场景中,一个人扔,一个人扫,就类似于Minor GC,这时候,并不会影响扔垃圾的人,然后一旦10个人同时仍,而且很快就没地方仍了,这时候,就会触发Full GC,然后JVM下令,你们暂时都别仍了,等我什么时候回收完垃圾了,你们在仍,现在大家清楚了吧,所谓的10个人,就是类似我们成千上百的java类,在不停的执行任务,所谓的清洁工,就是我们的GC机制,所以,大家在平时编码的时候,一定注意尽量少造点垃圾对象,这样触发FULL GC的几率,才会变小。

时间: 2024-11-01 19:02:44

透视JVM之垃圾回收的相关文章

JVM的垃圾回收机制详解和调优

JVM的垃圾回收机制详解和调优 gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存.java语言并不要求jvm有gc,也没有规定gc如何工作.不过常用的jvm都有gc,而且大多数gc都使用类似的算法管理内存和执行收集操作. 1.JVM的gc概述 gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存.java语言并不要求jvm有gc,也没有规定gc如何工作.不过常用的jvm都有gc,而且大多数gc都使用类似的算法管理内存和执行收集操作. 在充分理解了垃圾收集算法和执行

03 JVM的垃圾回收机制

1.前言 理解JVM的垃圾回收机制(简称GC)有什么好处呢?作为一名软件开发者,满足自己的好奇心将是一个很好的理由,不过更重要的是,理解GC工作机制可以帮助你写出更好的Java程序. 在学习GC前,你应该知道一个技术名词:"stop-the-world" ,无论你选择哪种GC算法,"stop-the-world"都会发生."stop-the-world"意味着JVM停止应用程序,而去进行垃圾回收.当"stop-the-world&quo

JVM的垃圾回收机制 总结(垃圾收集、回收算法、垃圾回收器)

如果想了解Java内存模型参考:jvm内存模型-和内存分配以及jdk.jre.jvm是什么关系(阿里,美团,京东) 相信和小编一样的程序猿们在日常工作或面试当中经常会遇到JVM的垃圾回收问题,有没有在夜深人静的时候详细捋一捋JVM垃圾回收机制中的知识点呢?没时间捋也没关系,因为小编接下来会给你捋一捋. 一. 技术背景你要了解吧 二. 哪些内存需要回收? 2.1 引用计数算法 2.1.1 算法分析 2.1.2 优缺点 2.1.3 是不是很无趣,来段代码压压惊 2.2 可达性分析算法 2.3 Jav

JVM虚拟机垃圾回收(GC)算法及优缺点

一.什么是GC GC是jvm的垃圾回收,垃圾回收的规律和原则为: 次数上频繁收集新生区(Young) 次数上较少收集养老区(Old) 基本上不动永久区(Perm) 二.GC算法(分代收集算法) GC总共有四大算法,分别是: ①引用计数法 ②复制算法(Copying) ③标记清除(Mark-Sweep) ④标记压缩(Mark-Compact) ⑤标记清除压缩(Mark-Sweep-Compact) 1.1 引用计数法 1.2 复制算法(Copying) 复制算法主要用在新生代中. 1.2.1 复制

深入理解JVM之垃圾回收详解

一.垃圾收集的意义 在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象:而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾.JVM的一个系统级线程会自动释放该内存块.垃圾收集意味着程序不再需要的对象是"无用信息",这些信息将被丢弃.当一个对象不再被引用的时候,内存回收它占领的空间,以便空间被后来的新对象使用.事实上,除了释放没用的对象,垃圾收集也可以清除内存记录碎片.由于创建对象和垃圾收集器释放丢弃对象所占的内存空间,内

jvm的垃圾回收机制

jvm的垃圾(GC)回收机制,我就想java的垃圾不是jvm自己处理吗,不用我们去像过去C,C++似的需要我们程序员来手动处理,这也是jvm的好处,但话是这么说,我却没有弄明白,jvm是怎么样来进行处理的,然后我就百度了一下看了看,发现有四大处理器 1) 标记-清除收集器 Mark-Sweep 2) 复制收集器        Copying 3) 标记-压缩收集器 Mark-Compact 4) 分代收集器 Generational 我们可以来以图解的方式看看各个处理器的作用以及不足之处: 1)

JVM常见垃圾回收算法

jdk1.7.0_79 众所周知,Java是一门不用程序员手动管理内存的语言,全靠JVM自动管理内存,既然是自动管理,那必然有一个垃圾内存的回收机制或者回收算法.本文将介绍几种常见的垃圾回收(下文简称GC)算法. 在Java堆上分配一个内存给实例对象时,此时在虚拟机栈上引用型变量就会存放这个实例对象的起始地址. Object obj = new Object();  现在如果我们将变量赋值为null. obj = null; 此时可以看到Java堆上的实例对象无法再次引用它,那么它就是被GC的对

JVM:垃圾回收机制和调优手段

转载请注明出处: jiq?钦's technical Blog - 季义钦 引言: 我们都知道JVM内存由几个部分组成:堆.方法区.栈.程序计数器.本地方法栈 JVM垃圾回收仅仅针对公共内存区域即:堆和方法区进行. 本文主要讨论两点,一是垃圾回收策略,二是调优的方法. 一.垃圾回收机制 1.1 分代管理 将堆和方法区按照对象不同年龄进行分代: u  堆中会频繁创建对象,基于一种分代的思想,按照对象存活时间将堆划分为新生代和旧生代两部分,我们不能一次垃圾回收新生代存活的对象就放入旧生代,而是要经过

jvm的垃圾回收原理

什么是垃圾回收? 垃圾回收是Java中自动内存管理的另一种叫法.垃圾回收的目的是为程序保持尽可能多的可用堆(heap). JVM会删除堆上不再需要从堆引用的对象. 用一个例子解释垃圾回收? 比方说,下面这个方法就会从函数调用. void method(){ Calendar calendar = new GregorianCalendar(2000,10,30); System.out.println(calendar); } 通过函数第一行代码中参考变量calendar,在堆上创建了Grego