JVM 的GC算法和垃圾收集器
1.标记清除算法
黑色部分代表可回收对象,灰色部分代表存活对象,绿色部分代表未使用的。
最基础的收集算法就是标记清除算法如同他名字一样,算法分为"标记"和"清除"两个阶段:首先标记出所有需要回收的对象,在标记完成后同一回收所有被标记的对象,
标记的过程就是我们之前讲过的可达性分析算法。当需要回收时,我们把黑色标记的部分进行回收。
标记算法优缺点:
优点:简单直接易懂
缺点:
1、空间问题:标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时,无法找到足够连续内存而不得不提前触发另一次垃圾收集动作。
例如每个格子都是1K,要分配5k怎么办?只能提前进行垃圾收集了。
2、效率问题:标记和清除两个过程效率都不高。
2.复制算法
为了解决效率的问题,"复制算法"应用而生,复制算法过程:它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块,当这一块内存用完了,
就将还存活者的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。这样使得每次都是针对整个半区进行内存回收,
内存分配时也就不用考虑内存碎片等复杂情况,只要移动堆顶指针,按顺序分配内存即可。
优缺点:
优点:实现简单,运行高效。
缺点:1、这种算法的代价时将内存缩小了原来的一半,代价内存利用率不高。
2、在对象存活率较高时就要进行较多的复制操作,效率将会降低
3、标记整理算法
为了解决复制算法的这些缺点,提出了标记整理算法。标记整理算法过程:标记过程仍然与"标记—清除"算法一样,
但后续的步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。
4、分代收集算法
每种算法都有优缺点:那GC采用什么算法?把算法都用上,集百家之所长。为什么JVM的GC要分代收集?因为对象存过周期不同,IBM研究过,百分之90以上的对象都是"朝生夕死",生存周期很短,不到10%需要长期存活,按照这样的对象存活时间就可以分为两个区:新生代和老年代。老年代是指存活超过一定时间的,存活时间指对象活过多少次(默认为15次)GC,就成为老年代。
基本上我们所有new出的所有对象都是在新生代进行分配。新生代又分为不同的区段:Eden区(伊甸园)和Survivor区(幸存者)。新生代采用的算法是复制算法,因为百分之90以上的对象都是"朝生夕死",所以大部分对象真正存活的对象不多,需要移动的对象也不多,同时复制算法内存整理后内存非常规整。
新生代分为1个Eden区和2个Survivor区(分别叫from和to)。默认比例为8:1,为啥默认会是这个比例,因为一般情况下新创建的对象都会被分配到Eden区(一些大对象特殊处理),这些对象经过第一次Minor GC后,如果仍然存活,将会被移到Survivor区。对象在Survivor区中每熬过一次Minor GC,年龄就会增加1岁,当它的年龄增加到一定程度时,就会被移动到年老代中。
在GC开始的时候,对象只会存在于Eden区和名为“From”的Survivor区,Survivor区“To”是空的。紧接着进行GC,Eden区中所有存活的对象都会被复制到“To”,而在“From”区中,仍存活的对象会根据他们的年龄值来决定去向。年龄达到一定值(年龄阈值,可以通过-XX:MaxTenuringThreshold 来设置)的对象会被移动到年老代中,没有达到阈值的对象会被复制到“To”区域。经过这次GC后,Eden区和From区已经被清空。这个时候,“From”和“To”会交换他们的角色,也就是新的“To”就是上次GC前的“From”,新的“From”就是上次GC前的“To”。不管怎样,都会保证名为To的Survivor区域是空的。Minor GC会一直重复这样的过程,直到“To”区被填满,“To”区被填满之后,会将所有对象移动到年老代中。
新生代的垃圾回收叫minor gc,老年代的gc叫做 major gc,整个堆的gc叫做full gc。
老年代中因为对象存活率高、没有额外空间对它进行分配担保,就必须使用"标记清除"或者"标记整理" 算法来进行回收。
新生代垃圾收集器:
从图中可以看出新生代的垃圾收集器有三种,都是采用的复制算法。
Stop-The-World:Java中一种全局暂停的现象,全局停顿,所有Java代码停止,native代码可以执行,但不能和JVM交互多半由于GC引起
Serial 新生代的单线程垃圾回收,采用复制算法,进行垃圾回收时,工作线程必须停止, 会产生Stop the world 现象。
ParNew垃圾收集器是Serial,收集器的多线程版本,搭配CMS垃圾回收器的首选
ParallelScavenge类似ParNew,更加关注吞吐量,达到一个可控制的吞吐量;本身是Server级别多CPU机器上的默认GC方式,主要适合后台运算不需要太多交互的任务;
老年代的垃圾收集器:
SerialOld:jdk7/8默认的老生代垃圾回收器Client模式下虚拟机使用
ParallelOld:ParallelScavenge收集器的老年代版本,为了配合Parallel Scavenge的面向吞吐量的特性而开发的对应组合;在注重吞吐量以及CPU资源敏感的场合采用
CMS:尽可能的缩短垃圾收集时用户线程停止时间;缺点在于:1.内存碎片2.需要更多cpu资源3.浮动垃圾问题,需要更大的堆空间
重视服务的响应速度、系统停顿时间和用户体验的互联网网站或者B/S系统。互联网后端目前cms是主流的垃圾回收器;
G1:JDK1.7才正式引入,采用分区回收的思维,基本不牺牲吞吐量的前提下完成低停顿的内存回收;可预测的停顿是其最大的优势;
面向服务端应用的垃圾回收器,目标为取代CMS
新生代收集器有3种,老年代收集器有三种,那么是不是任意搭配就可以?其实是不可以的那么怎么搭配使用呢?其实只有在分代收集示意图中连线了的才可以搭配一起使用。
那么如何查看本机的垃圾回收器是哪种收集器?打开命令窗口输入命令:java -XX:+PrintCommandLineFlags -version,运行会得到如下图的结果:
-XX:+UseParallelGC就指明了新生代使用ParallerGC收集器(Parallel Scavenge也叫Paraller),老年代使用Serial Old收集器。
-XX:+UseSerialGC :Serial/Serial Old收集器这样组合,新生代和老年代都用串行收集器。
-XX:+UseParallerOldGC:新生代使用Parallel Scavenge,老年代使用Parallel Old
-XX:+UseConcMarkSweepGC ,表示新生代使用ParNew,老年代的用CMS。
JVM 的GC算法和垃圾收集器的更多相关文章
- JVM(二)GC算法和垃圾收集器
前言 垃圾收集器(Garbage Collection)通常被成为GC,诞生于1960年MIT的Lisp语言.上一篇介绍了Java运行时区域的各个部分,其中程序计数器.虚拟机栈.本地方法栈3个区域随线 ...
- JVM垃圾回收算法 及 垃圾收集器
摘自<深入理解Java虚拟机> 一.什么是: GC算法是 方法论,那么垃圾收集器就是具体的 实现. 二.四种 垃圾回收算法 1.标记-清除算法:最基础的收集算法:不足有两点:1标记和清除两 ...
- JVM之GC算法、垃圾收集算法——标记-清除算法、复制算法、标记-整理算法、分代收集算法
标记-清除算法 此垃圾收集算法分为“标记”和“清除”两个阶段: 首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记对象,它的标记过程前面已经说过——如何判断对象是否存活/死去 死去的对象就会 ...
- JVM初探- 内存分配、GC原理与垃圾收集器
JVM初探- 内存分配.GC原理与垃圾收集器 标签 : JVM JVM内存的分配与回收大致可分为如下4个步骤: 何时分配 -> 怎样分配 -> 何时回收 -> 怎样回收. 除了在概念 ...
- java虚拟机学习-JVM内存管理:深入垃圾收集器与内存分配策略(4)
Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 概述: 说起垃圾收集(Garbage Collection,下文简称GC),大部分人都把这项 ...
- JVM性能优化系列-(2) 垃圾收集器与内存分配策略
2. 垃圾收集器与内存分配策略 垃圾收集(Garbage Collection, GC)是JVM实现里非常重要的一环,JVM成熟的内存动态分配与回收技术使Java(当然还有其他运行在JVM上的语言,如 ...
- 3-JVM垃圾回收算法和垃圾收集器
垃圾回收算法和垃圾收集器 1.什么是垃圾回收 对于内存当中无用的对象进行回收,如何去判断一个对象是不是无用的对象. 引用计数法: 每个对象中都会存储一个引用计数,每增加一个引用就+1,消失一个引用就- ...
- [JVM-3]Java垃圾回收(GC)机制和垃圾收集器选择
哪些内存需要回收? 1.引用计数法 这个算法的实现是,给对象中添加一个引用计数器,每当一个地方引用这个对象时,计数器值+1:当引用失效时,计数器值-1.任何时刻计数值为0的对象就是不可能再被使用的.这 ...
- 深入理解JVM(5)——HotSpot垃圾收集器详解
HotSpot虚拟机提供了多种垃圾收集器,每种收集器都有各自的特点,没有最好的垃圾收集器,只有最适合的垃圾收集器.根据新生代和老年代各自的特点,我们应该分别为它们选择不同的收集器,以提升垃圾回收效率. ...
随机推荐
- Html头部meta标签
meta元素有4个属性:name.http-equiv.content.charset.meta标签通过name属性来表述页面文档的元信息,通过http-equiv属性设置http请求指令,通过c ...
- pm2入门
简介 PM2是node进程管理工具,可以利用它来简化很多node应用管理的繁琐任务,如性能监控.自动重启.负载均衡等,而且使用非常简单. 安装 全局安装,简直不能更简单. npm install -g ...
- 主成分分析(PCA)原理与实现
主成分分析原理与实现 主成分分析是一种矩阵的压缩算法,在减少矩阵维数的同时尽可能的保留原矩阵的信息,简单来说就是将 \(n×m\)的矩阵转换成\(n×k\)的矩阵,仅保留矩阵中所存在的主要特性,从 ...
- JS高阶---IIFE&&函数前加;
IIFE( 立即调用函数表达式)是一个在定义时就会立即执行的 JavaScript 函数. 全称为Immediately Invoked Function Expression 有时如果不加:会出现一 ...
- python 登录并获取session,使用session新增ecshop的草稿
,"consignee":"冬天","email":"12345@qq.com","address" ...
- SpringBoot注解分析解释
使用注解的优势: 1.采用纯java代码,不在需要配置繁杂的xml文件 2.在配置中也可享受面向对象带来的好处 3.类型安全对重构可以提供良好的支持 4.减少复杂配置文件的同时亦能享受到springI ...
- selenium 简介 及浏览器配置
简介: Selenium是一款基于web应用程序的开源测试工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.Selenium是一个自动化的web应用功能测试工具. Seleniu ...
- SSH使用ProxyCommand通过代理服务器远程连接其他服务器
当前环境拓扑图: 用户管理海外服务器,通过公网SSH远程时,由于网络质量原因公网丢包严重,这就导致管理员在对海外云主机进行管理时体验较差,表现形式可能是由于公网丢包严重执行命令卡顿,或者SSH进程 ...
- 流媒体服务器 red5
https://github.com/Red5/red5-server/releases/tag/v1.0.7-RELEASE 打开此链接 再tar包那里 复制链接地址 Wget此链接地址 W ...
- JAVA基础概念(三)
JAVA方法入参和返回类型 方法入参 基础数据类型 引用数据类型 修饰符 返回类型 方法名(参数类型 参数名,参数类型 参数名...){//方法体return} 方法返回类型 return xxx 具 ...