JVM系列-分代收集垃圾回收
Java自动垃圾回收(Automatic Garbage Collection)是自动回收堆上不再使用的内存,new的对象在程序中没有引用指向它,就会被回收。回收的实现很多,有Reference Counting Collector/Tracing Collector/Compacting Collector/Coping Collector/Generational Collector/Adaptive Collector。本文记录的是HotSpot Java VM采用的Generational Collector(分代收集器)。
为什么分代?
下图是随着时间的推移,经历垃圾回收后存活下的数据大小情况。可以看出大部分对象存活期很短,随着时间的推移越来越少的对象存活下来。因此,可以针对不同的堆内存采取不同的回收频率和方法,以提高JVM性能。
堆内存分代概念
下图是Generation GC对内存结构的划分:
Eden:用于new对象时分配的内存空间,大部分初始new的对象位于该空间
Survivor Space:在eden中经历垃圾回收后,存活下来的对象被存储在该空间
tenured Space:在survivor space中存在了一段时间的对象会被挪到该空间
Permanent Space:JVM使用的元数据,如classloader加载的class/method定义(反射后的数据)。
Code Cache:用于编译和存储原代码
其中Permanent Space和Code Cache不属于generation collector回收范围。但是当Permanent Space已用完,且需要加载新class时,会触发Full GC对Permanent进行回收,卸载(清除)那些不再被需要的class。
如何分代收集
new对象会最初分配在eden中,当eden满时触发minor garbage collection。
Minor GC(又称作Young GC)针对young generation:
- eden/S0中存活的对象被复制到S1中,eden/S0被清空
- 每次minor gc,存活对象的age会加1,当age超过阈值后,对象被存到old generation中。
- S0和S1是相对的,第一次Minor GC时S0/S1都是空的,从eden往S0复制,第二次minor gc就是从eden/S0往S1复制,下一次是eden/S1到S0,以后依次类推。
Minor GC采用的是复制收集,young generation中的对象大部分是不再使用,所以复制存活下来的对象到新空间,旧空间整体回收,这样的一个过程会更快。
随着Minor GC的发生,被promoted到old generation的对象越来越多,当old generation满时就触发了major garbage collection。Major GC(又称作Old GC)针对old generation,采取marking-deletion-compact(标记-清除-压缩内存)的方法。(补:压缩内存,就是把活着的对象放在一块,省出连续的空闲内存,便于分配)
通常Major GC又被认为是Full GC,因为Major GC发生时会伴随着Minor GC:一次Minor GC将存活对象放到old generation时导致old generation满了,从而导致Major GC。这一段时间整个堆内存表现出的现象是都进行了garbage collection。
建议
Minor/Major GC都是Stop the World事件,应用程序会停止执行,直到GC完成。Major GC发生时,整个堆内存都受到了影响,持续时间长。
所以应该尽量避免或减少Major GC(减少被放到old generation的对象);尽量最大化堆内存。
实际使用
在启动java程序时通过设置相关命令参数调节垃圾回收的方法、阈值或频率来优化GC对程序的影响,常用命令如下:
| Switch | Description |
-Xms |
Sets the initial heap size for when the JVM starts. |
-Xmx |
Sets the maximum heap size. |
-Xmn |
Sets the size of the Young Generation. |
| -XX:PermSize | Sets the starting size of the Permanent Generation. |
| -XX:MaxPermSize | Sets the maximum size of the Permanent Generation |
GC的串并行
串行GC在JavaSE 5/6上是默认方式,常用于对暂停时间要求不高、客户端类型的应用程序上,也适用于应用程序的数目比CPU多的情况,这样GC时JVM之间的影响小。MB级别的堆内存进行Full GC时只需要几秒。设置的命令是-XX:+UseSerialGC。
并行GC使用多线程进行Minor GC,线程数默认与CPU数相等。设置的相关命令是-XX:+UseParallelGC和-XX:ParallelGCThreads=<desired number>(指定线程数)。-XX:+UseParallelOldGC会设置Minor GC和Major GC都采用多线程。
CMS
并发标记清除收集器(Concurrent Mark Sweep)用于old generation的垃圾回收,它尽力减少程序的暂停时间,GC工作和应用程序的线程并发执行。它不做compact(压缩)堆内存,省去了内存的拷贝和移动。当内存碎片过多无法满足分配时,就直接重新分配一块更大的堆内存。CMS适用于webserver或者查询类的应用。
相关命令:-XX:+UseConcMarkSweepGC和-XX:ParallelCMSThreads=<n>(设置并行线程数)
G1 Garbage Collector
G1回收器在Java7中被引进,希望能取代CMS,它主要是并发、增量式的compact内存,以取得低暂停。相关命令:-XX:+UseG1GC
一个实例
java -Xmx12m -Xms3m -Xmn1m -XX:PermSize=20m -XX:MaxPermSize=20m -XX:+UseParallelOldGC -jar Java2demo.jar
参考:http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html
JVM系列-分代收集垃圾回收的更多相关文章
- JVM的永久代会发生垃圾回收吗?
垃圾回收不会发生在永久代中.当永久代满或者超过临界值时,就会触发完全垃圾回收(Full GC).如果仔细查看垃圾收集器中的输出信息,就会发现永久代也是被回收的.这就是正确的永久代大小对避免Full G ...
- JVM的stack和heap,JVM内存模型,垃圾回收策略,分代收集,增量收集
(转自:http://my.oschina.net/u/436879/blog/85478) 在JVM中,内存分为两个部分,Stack(栈)和Heap(堆),这里,我们从JVM的内存管理原理的角度来认 ...
- JVM虚拟机学习一:垃圾回收算法总结
1.java虚拟机中涉及到的数据类型 Java虚拟机中,数据类型可以分为两类:基本类型和引用类型. 基本类型的变量保存原始值,即:他代表的值就是数值本身:而引用类型的变量保存引用值.“引用值”代表了某 ...
- 推荐收藏系列:一文理解JVM虚拟机(内存、垃圾回收、性能优化)解决面试中遇到问题(图解版)
欢迎一起学习 <提升能力,涨薪可待篇> <面试知识,工作可待篇 > <实战演练,拒绝996篇 > 欢迎关注我博客 也欢迎关注公 众 号[Ccww笔记],原创技术文章 ...
- JVM之GC算法、垃圾收集算法——标记-清除算法、复制算法、标记-整理算法、分代收集算法
标记-清除算法 此垃圾收集算法分为“标记”和“清除”两个阶段: 首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记对象,它的标记过程前面已经说过——如何判断对象是否存活/死去 死去的对象就会 ...
- JVM垃圾收集算法——分代收集算法
分代收集算法(Generational Collection): 当前商业虚拟机的垃圾收集都采用"分代收集算法". 这种算法并没有什么新的思想,只是根据对象存活周期的不同将内存划分 ...
- JVM的内存分配与垃圾回收策略
自动内存管理机制主要解决了两个问题:给对象分配内存以及回收分配给对象的内存. >>垃圾回收的区域 前面的笔记中整理过虚拟机运行数据区,再看一下这个区域: 注意在这个Runtime Data ...
- Java虚拟机:JVM内存分代策略
版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! Java虚拟机根据对象存活的周期不同,把堆内存划分为几块,一般分为新生代.老年代和永久代(对HotSpot虚拟机而言),这就是JVM的内存 ...
- jvm学习笔记一(垃圾回收算法)
一:垃圾回收机制的原因 java中,当没有对象引用指向原先分配给某个对象的内存时候,该内存就成为了垃圾.JVM的一个系统级线程会自动释放该内存块.垃圾回收意味着程序不再需要的对象是"无用信息 ...
随机推荐
- 【Mybatis架构】 延迟加载
在上一篇博客中,我们提到过有关于Mybatis输出映射中resultMap能够实现延迟加载的事,然而真的是所有的resultMap都能实现延迟加载还是咋地啊?现在我们就来对那一句话做一下阐述和实例说明 ...
- dos下对mysql的简单操作(linux类似)
>>>>>>>>>>>>>>>>>>>> 基础入门语句10条 1. 连接服务器 ...
- js 实现表格的可编辑状态
实现表格的可编辑,点击修改以后可以编辑,代码如下: <!DOCTYPE HTML> <html> <head> <meta charset="utf ...
- 禁用ViewPager边界滑动效果(转)
反射设置方法 private EdgeEffectCompat leftEdge; private EdgeEffectCompat rightEdge; public void DisableLRS ...
- 一些关于HTML与CSS的总结与实际应用
//学习前端也快一年了,觉得有必要好好总结一下这一年来学过的知识.一些是前辈们的精华,文章最后会讲地址一一放出,若原作者有任何介意,请及时联系我删除. 关于DOCTYPE 1.DOCTYPE的作用是什 ...
- 总结30个CSS3选择器(转载)
或许大家平时总是在用的选择器都是:#id .class 以及标签选择器.可是这些还远远不够,为了在开发中更加得心应手,本文总结了30个CSS3选择器,希望对大家有所帮助. 1 *:通用选择器 * ...
- U-Boot Driver Model领域模型设计
需求分析 在2014年以前,uboot没有一种类似于linux kernel的设备驱动模型,随着uboot支持的设备越来越多,其一直受到如下问题困扰: 设备初始化流程都独立实现,而且为了集成到系统,需 ...
- 关于Web服务器的认识
马上就要毕业了,也要开始找工作了,大学写了这么多代码了,却没有好好总结一下常用的概念很是遗憾额,就通过这篇博客记录一下我最常用的一些知识好了. 说到Web服务器,有很多文章都介绍的很好,之前看到一篇非 ...
- jQuery中设置form表单中action的值的方法
下面介绍在jQuery中设置form表单中action的值的方法. $("#myFormId").attr("action", "userinfo.s ...
- java的基础知识运算符
一.运算符. 1.算数运算符:+,-,*,/,% 2.自增自减 :++ ,-- ++在前 先运算在赋值 ++在后 先赋值后运算 -- 减减同上. 3.赋值运算符 : = ,+=,-=,*=,/= 4. ...