JVM的GC概述
JVM的GC概述
GC即垃圾回收,是指jvm用于释放那些不再使用的对象所占用的内存。
在充分理解了垃圾收集算法和执行过程后,才能有效的优化它的性能。
有些垃圾收集专用于特殊的应用程序。比如,实时应用程序主要是为了避免垃圾收集中断,而大多数OLTP应用程序则注重整体效率。
垃圾收集的目的在于清除不再使用的对象。gc通过确定对象是否被活动对象引用来确定是否收集该对象。两种常用的方法是引用计数和对象引用遍历。
引用计数
引用计数存储对特定对象的所有引用数,也就是说,当应用程序创建引用以及引用超出范围时,jvm必须适当增减引用数。当某对象的引用数为0时,便可以进行垃圾收集。
对象引用遍历
早期的jvm使用引用计数,现在大多数jvm采用对象引用遍历。对象引用遍历从一组对象开始,沿着整个对象图上的每条链接,递归确定可到达(reachable)的对象。如果某对象不能从这些根对象的一个(至少一个)到达,则将它作为垃圾收集。在对象遍历阶段,gc必须记住哪些对象可以到达,以便删除不可到达的对象,这称为标记(marking)对象。
基本的回收算法:
空间维度:标记-清除、标记-压缩、标记-复制、增量回收、分代回收
时间维度:串行回收、并发回收、并行回收
标记-清除:
标记清除的算法最简单,主要是标记出来需要回收的对象,然后然后把这些对象在内存的信息清除,会产生大量内存碎片。

标记-压缩
有时也叫标记-清除-压缩收集器,这个算法是在标记-清除的算法之上进行剪切操作,将存活对象压缩在一起,减少内存碎片。由于压缩空间需要一定的时间,会影响垃圾收集的时间。

标记-复制
这个算法是把内存分配为两个空间,一个空间(A)用来负责装载正常的对象信息,另外一个内存空间(B)是垃圾回收用的。
每次把空间A中存活的对象全部复制到空间B里面,在一次性的把空间A删除。
这个算法在效率上比标记-清除-压缩高,但是需要两块空间,对内存要求比较大,内存的利用率比较低。适用于短生存期的对象,持续复制长生存期的对象则导致效率降低。

增量回收:
增量回收器:把堆分为多个域,每次对从一个域进行垃圾回收。这样只会早点一小部分程序暂停。
分代回收:
基于对对象生命周期分析后得出的垃圾回收算法。把对象分为年青代、年老代、持久代,对不同生命周期的对象使用不同的算法进行回收。
串行回收:
用单线程处理所有垃圾回收工作,因为无需多线程交互,所以效率比较高。但是,也无法使用多处理器的优势,所以此收集器适合单处理器机器

并行回收:
用多线程处理所有垃圾回收工作,利用多核处理器的优势。对于空间不大的区域(如young generation),采用并行收集器停顿时间很短,回收效率高,适合高频率执行。但是如果线程数量过多,导致线程之间频繁调度,也会影响性能。一半并行收集的线程是处理器的个数。

并发回收:
并发收集器GC时GC线程和应用线程大部分时间是并发执行,只是在初始标记(initial mark)和二次标记(remark)时需要stop-the-world,这可以大大缩短停顿时间(pause time),所以适用于响应时间优先的应用,减少用户等待时间。由于GC是和应用线程并发执行,只有在多CPU场景下才能发挥其价值,在一个N个处理器的系统上,并发收集部分使用K/N个可用处理器进行回收,一般情况下1<=K<=N/4。在执行过程中还会产生新的垃圾floating garbage(浮动垃圾),如果等空间满了再开始GC,那这些新产生的垃圾就没地方放了(并发收集器一般需要20%的预留空间用于这些浮动垃圾),这时就会启动一次串行GC,等待时间将会很长,所以要在空间还未满时就要启动GC。mark和sweep操作会引起很多碎片,所以间隔一段时间需要整理整个空间,否则遇到大对象,没有连续空间也会启动一次串行GC。采用此收集器,收集频率不能大,否则会影响到cpu的利用率,进而影响吞吐量。

JVM的GC触发原理
JVM的GC主要是对堆内存的回收,
一般把新生代的GC称为minor GC ,把老年代的GC成为 full GC,所谓full gc会先出发一次minor gc,然后在进行老年代的GC。
首先想eden区申请分配空间,如果空间够,就直接进行分配,否则进行一次Minor GC。
minor GC 首先会对Eden区的对象进行标记,标记出来存活的对象。然后把存活的对象copy到From空间。
如果From空间足够,则回收eden区可回收的对象。
如果from内存空间不够,则把From空间存活的对象复制到To区,
如果TO区的内存空间也不够的话,则把To区存活的对象复制到老年代。
如果老年代空间也不够(或者达到触发老年年垃圾回收条件的话)则触发一次full GC。
简单方向就是Eden->From->To->Old,如下图所示:

默认是不会对持久带(方法区)进行垃圾回收的,设置参数可回收:-XX:+CMSClassUnloadingEnabled
JVM支持的GC收集器
JVM采用的是分代回收,不同代有不同的垃圾收集器
如图所示:连线的是可以组合使用

各个收集器的细节我就不在这里COPY/PASTE了,SerialOld收集器在书的图中没有,是我后加上的,其实很少使用。
JVM的GC概述的更多相关文章
- [转帖]Java虚拟机(JVM)体系结构概述及各种性能参数优化总结
Java虚拟机(JVM)体系结构概述及各种性能参数优化总结 2014年09月11日 23:05:27 zhongwen7710 阅读数 1437 标签: JVM调优jvm 更多 个人分类: Java知 ...
- Linux使用jstat命令查看jvm的GC情况
Linux使用jstat命令查看jvm的GC情况 http://www.open-open.com/lib/view/open1390916852007.html http://www.aiuxian ...
- poptest老李谈jvm的GC
poptest老李谈jvm的GC poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:90882 ...
- JVM内存管理概述与android内存泄露分析
一.内存划分 将内存划分为六大部分,分别是PC寄存器.JAVA虚拟机栈.JAVA堆.方法区.运行时常量池以及本地方法栈. 1.PC寄存器(线程独有):全称是程序计数寄存器,它记载着每一个线程当前运行的 ...
- Linux使用jstat命令查看jvm的GC情况(转)
B. jstack jstack主要用来查看某个Java进程内的线程堆栈信息.语法格式如下: 1 jstack [option] pid 2 jstack [option] executable co ...
- jvm的GC日志分析 [转]
jvm的GC日志分析 标签: jvm内存javagc 2015-06-22 16:37 1566人阅读 评论(1) 收藏 举报 分类: Java(4) JVM的GC日志的主要参数包括如下几个: ...
- JVM 的GC算法和垃圾收集器
1.标记清除算法 黑色部分代表可回收对象,灰色部分代表存活对象,绿色部分代表未使用的.最基础的收集算法就是标记清除算法如同他名字一样,算法分为"标记"和"清除" ...
- JVM&G1 GC 学习笔记(一)
在入门学习JVM的过程中,我们需要先了解关于JVM的知识中有哪些关键词或关键术语,今天在看完书后我想记录下来. Xms64mb 虚拟机初始化时设置内存大小为64mb Xmx256mb 设定虚拟 ...
- 深入理解JVM+G1+GC.pdf (中文版带书签)
目录 序 VII前言 IX 第1章 JVM & GC基础知识 11.1 引言 21.2 基本术语 31.2.1 Java相关术语 41.2.2 JVM/GC通用术语 241.2.3 G1涉及术 ...
随机推荐
- poj 1702 三进制问题
Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 3906 Accepted: 1924 Description Eva h ...
- Linux计划任务crontab运行脚本不正确的问题
问题的由来 写好的程序希望在崩溃之后能够自启动,于是利用linux的crontab功能,添加一个计划任务,每分钟执行一个脚本查看需要监控的进程是否还在,如果不在则启动之,否则不做任何事情.这么一个简单 ...
- How and Where Concurrent Asynchronous I/O with ASP.NET Web API 对异步编程分析的非常的好
How and Where Concurrent Asynchronous I/O with ASP.NET Web API http://www.tugberkugurlu.com/archive/ ...
- Linux Shell变量
200 ? "200px" : this.width)!important;} --> 介绍 变量是shell脚本中必不可少的组成部分,在脚本中使用变量不需要提前声明.在ba ...
- 基于java的设计模式入门(1)——为什么要学习设计模式
大年初一,楼主在这里给大家拜年,祝大家码上升职加薪,码上有对象结婚,码上有车有房,幸福安康. 过完年,回学校注册报道之后,大概就要回深圳到公司开始实习了.提高自己,无非就有两种方式,一是看书学习,二是 ...
- Android多线程分析之五:使用AsyncTask异步下载图像
Android多线程分析之五:使用AsyncTask异步下载图像 罗朝辉 (http://www.cnblogs.com/kesalin) CC 许可,转载请注明出处 在本系列文章的第一篇<An ...
- Spring-Context之八:一些依赖注入的小技巧
Spring框架在依赖注入方面是非常灵活和强大的,多了解点一些注入的方式.方法,绝对能优化配置. idref idref属性可以传入一个bean的名称,虽然它是指向一个bean的引用,但是得到的是该b ...
- ./在Linux下是什么意思
在网上找的答案: . 在这里表示的是当前目录,就像 .. 表示上级目录一样. 这个 / 表示的是目录级别的分隔符,他之前的就是目录名,./aaa/ 表明的就是 . (也就是当前目录)下面的 aaa 目 ...
- Atitit 为什么网络会有延时 电路交换与分组交换的区别
Atitit 为什么网络会有延时 电路交换与分组交换的区别 按道理,网络是电子设备联网,应该达到光速才对.. 本质上因为互联网基于分组交换而不是电路交换. 分组交换相当于队列方式,别人发你的数据包先存 ...
- 邮件开发——base64账号密码转换
package com.hq.base64; import java.io.BufferedReader; import java.io.FileInputStream; import java.io ...