JVM探索之内存管理(三)
上节我们介绍了JVM垃圾回收的原则,还有几个垃圾收集算法:标记-清除算法、复制算法、标记整理算法、分代收集算法;现在将要说HotSpt的垃圾收集器,这小节将只是理论。
Java虚拟机规范对垃圾收集器的具体实现并没有任何规定,所以不同厂商、不同版本的虚拟机提供的垃圾收集器会有很大的不同。下面所介绍的收集器只是HotSpt1.7的垃圾收集器。
HotSpot堆的瓜分
HotSpt它把内存空间分为几个区域:新生代、老年代、永久代;上节中也说到了分代垃圾收集算法的主要思想按对象的生命周期来进行分组;

如上图JVM把堆划分为Young、Old、Perm三大区域,对应着不能年龄的对象;然后又把Young分为:Eden、Survivor From、Survivor To三小块;各个区域存放对象的区别如下:
- Young区,所有新创建的对象都存储在Eden区域中,当Eden满后将会触发minor GC把Eden中存活的对象复制到一个Survivor中,然后另一个Survivor存活对象也复制到这个中,始终保持一个Survivor区域为空的。
- Old区存放的是Survivor满后触发minor GC后依然存活的对象,如果从Eden复制到Survivor的对象存不了也可以直接存到Old区中等。Old区满了就会触发Full GC回收整个堆内存。
- Perm区存储类、方法、等的元信息,Perm也会触发Full GC进行垃圾回收。
Sun有对各个区域给出建议的大小,Young区域为整个堆的1/4,Young中的Survivor为Young区域的1/8,安装JDK的时候有自带了visualvm工具,可以安装Visual GC插件来查看到JVM各个区域的垃圾回收情况,可以看到内存大小、GC时间、已使用大小、剩余大小等等信息如图:

垃圾收集器
HotSpot提供了七种类垃圾收集器:Serial 收集器、ParNew 收集器、Parallel Scavenge收集器、Serial Old收集器、Parallel Old 收集器、CMS 收集器、G1 收集器。
Serial 收集器是比较古老的一种收集器,不过到现在他还是JVM client模式中默认新生代的GC算法, Serial是单线程的,它在进行垃圾回收工作时会暂停所有其他工作,Sum称为:“Stop The World”,直到回收任务结束,然后Serial工作时占用的时间比较多但它比较简单新生代内存不大的情况下回收工作时间还是短到可以接收的,基本一秒以内。
ParNew 收集器与Serial Collector唯一不同的就是Serial Collector是单线程的,ParNew Collector是多线程的,ParNew Collector是JVM Server模式中默认的新生代GC算法。
Parallel Scavenge收集器 也是新生代收集算法,使用复制算法、并行的多线程,它的优势在于提高吞吐量,GC停顿的时间越短吞吐量就会越高,
Serial Old收集器为Serial的老年代版本,单线程、“标记-整理”算法,在Client模式下为虚拟机使用。
Parallel Old 收集器为Parallel Scavenge的老年代版本,使用多线程、“标记-清除算法”,
CMS(Concurrent Mark Sweep)收集器是以最短停顿时间为目标的收集器,使用了“标记清除”算法实现,不过这个收集器比前面几个收集器都要复杂,运作过程有这么几个步骤:
1、 初始标记(CMS initial mark)
2、 并发标记(CMS concurrent mark)
3、 重新标记(CMS remark)
4、 并发清除(CMS concurrent sweep)
在初始标记、重新标记的时候会“Stop The World”,初始标记标记出GC Roots能直接关联到的对象,并发标记进行GC Roots Tracing,重新标记修复在程序继续运行导致标记的变动,CMS也有不好的地方就是CMS会占用较多的CPU由于CMS是使用标记清除算法实现的,所以可能会导致较多的碎片。
G1收集器JDK1.7发布的时候才退出的算法,可以说是比较新的技术,相比CMS G1不会产生碎片,因为他使用的是“标记-整理”算法,G1还有就是能比较精确的空间停顿时间可以在不牺牲吞吐量的情况下进行垃圾回收,G1把整个Java堆(新生代、老年代)瓜分为多个独立区域,跟踪这些区域的垃圾堆积程度,然后维护一个优先列表,根据允许的时间优先回收垃圾最多的区域。
内存分配策略
内存的分配规则不是百分之百固定的,它取决与虚拟机的相关参数配置还有使用的垃圾收集器组合。这里说的只是最普遍的内存分配规则,这里只是说些理论,在下篇文章将会用代码去验证。
Eden优先分配
绝大多数情况下对象创建的时候在Eden区域分配,当分配的时候Eden中空间不足时将触发Minor GC,
较大对象直接进入老年代
较大对象:需要使用大量连续的内存空间的Java对象,常见的有:很长的字符串、数组,写代码的时候能避免尽量避免短命较大对象,因为大对象常常会引发GC。
生命周期较长的对象进入老年代
分代垃圾收集的思想就是按对象的生命周期来分开管理,虚拟机为每个对象定义了一个对象年龄计数器,对象在Eden区中经过一次Minor GC后仍存活并复制到Survivor中,对象年龄就为1,对象每在Survivor中度过一次Minor GC年龄将加1,当年龄到一定值(默认15)的时候对象将晋升到老年代。阀值可以通过参数设置,后面将介绍到。
动态年龄判定
虚拟机并不定死说必须达到MaxTenuringThreshold年龄才能晋升老年代;如在Survivor空间中相同年龄所有对象大小总和大于Survivor空间的一半,大于或等于该年龄的对象就可以直接进入老年代中,无需等到指定的年龄。
空间担保分配
年轻代在发生Minor GC时,虚拟机会检测每次晋升到老年代的平均大小是否大于老年代剩余的存储空间,比老年代剩余空间大则改为直接Full GC,如果小,则看HandlePromotionFailure设置是否允许担保失败,是则只会进行Minor GC,否则也要改为进行一次Full GC。
文章首发地址:Solinx
http://www.solinx.co/archives/58
JVM探索之内存管理(三)的更多相关文章
- JVM探索之——内存管理(一)
本系列的第一篇文章,预计本系列最后面会有两三个案例. Java与C.C++不一样Java不需要Coder进行手动内存管理,而这一切都交给JVM进行自动内存管理,这从某种程度上来说也减轻了我们Coder ...
- JVM探索之——内存管理(二)
上篇文章我们介绍了JVM所管理的内存结构也就是运行时数据区(Run-Time Data Areas),现在我们将介绍JVM的内存分配与回收静态内存分配与动态内存分配 JVM的内存分配主要分为两种:静态 ...
- JVM介绍&自动内存管理机制
1.介绍JVM(Java Virtual Machine,Java虚拟机) JVM是Java Virtual Machine的缩写,通常成为java虚拟机,作为Java可以进行一次编写,到处执行(Wr ...
- Linux内存描述之内存区域zone--Linux内存管理(三)
1 内存管理域zone 为了支持NUMA模型,也即CPU对不同内存单元的访问时间可能不同,此时系统的物理内存被划分为几个节点(node), 一个node对应一个内存簇bank,即每个内存簇被认为是一个 ...
- Linux内存描述之内存区域zone–Linux内存管理(三)
服务器体系与共享存储器架构 日期 内核版本 架构 作者 GitHub CSDN 2016-06-14 Linux-4.7 X86 & arm gatieme LinuxDeviceDriver ...
- PHP内核探索:内存管理开篇
内存是计算机非常关键的部件之一,是暂时存储程序以及数据的空间,CPU只有有限的寄存器可以用于存储计算数据,而大部分的数据都是存储在内存中的,程序运行都是在内存中进行的.和CPU计算能力一样, 内存也是 ...
- COCOS学习笔记--Cocod2dx内存管理(三)-Coco2d-x内存执行原理
通过上两篇博客.我们对Cocos引用计数和Ref类.PoolManager类以及AutoreleasePool类已有所了解,那么接下来就通过举栗子来进一步看看Coco2d-x内存执行原理是如何的. / ...
- Java Core - JVM运行时内存管理
在读正文之前,阅读以下两篇博客学习并理解堆栈.作用域.本地方法的概念. 作用域:https://www.cnblogs.com/AlanLee/p/6627949.html 操作数栈:https:// ...
- jvm之自动内存管理
一.运行时数据区 程序计数器(线程私有) 1.程序计数器占用jvm内存较小,主要用来记录当前线程所执行的字节码的位置,因为jvm的多线程都是通过cpu对线程进行来回切换,所以在某个确定的时间cpu只会 ...
随机推荐
- mysql与oracle常用函数及数据类型对比
最近在转一个原来使用oracle,打算改为mysql的系统,有些常用的oracle函数的mysql实现顺便整理了下,主要是系统中涉及到的(其实原来是专门整理过一个详细doc的,只是每次找word麻烦) ...
- SSH免密码登录过程解析和实现
SSH 为建立在应用层和传输层基础上的安全协议.SSH 是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议.利用SSH 协议可以有效防止远程管理过程中的信息泄露问题. 从客户端来看,SSH提 ...
- Spring4学习笔记1-HelloWorld与IOC和DI概述
1.安装环境 1.1安装eclipse,jdk 1.1安装Spring tool suite(非必要项) 2.spring HelloWorld 2.1 需要的jar包(spring官网下载:http ...
- 如何在BPM中使用REST服务(1):通过程序访问网页内容
这篇文章主要描述如何通过程序来访问网页内容,这是访问REST服务的基础. 在Java中,我们可以使用HttpUrlConnection类来实现,代码如下. package http.base; imp ...
- 基于 Node.js 平台的web开发框架-----express
express官网:---->传送门 express express框架有许多功能,比如路由配置,中间件,对于想配置服务器的前端来说,非常便捷 自从node发展之后,基于nodejs的开发框架 ...
- PHP清理跨站XSS xss_clean 函数 整理自codeigniter Security
PHP清理跨站XSS xss_clean 函数 整理自codeigniter Security 由Security Class 改编成函数xss_clean 单文件直接调用.BY吠品. //来自cod ...
- [deviceone开发]-QQ分享、微信分享和新浪微博分享
一.简介 该demo主要实现QQ分享.微信分享和新浪微博分享.(调试包请到论坛扫描对应二维码下载) 二.效果图 三.相关讨论 http://bbs.deviceone.net/forum.php?mo ...
- input输入样式,动画
模板描述:input输入样式 动画,有输入框也有搜索框的样式,多种多样,大家根据自己的喜欢来. 找网站SEO教程,网站模板,以及想要建立个人博客的朋友来涂志海个人博客网,这里有你想要的一切(万一没有的 ...
- 每次点击按钮后,判断页面是否已经有该行,没有弹出repeater的一行,并给他赋一个这行附值,没有则跳出
protected void btnAdd_click(object sender, EventArgs e) { try { //记录第几次追加 pressCount++; typeString.A ...
- JavaScript + SVG实现Web前端WorkFlow工作流DAG有向无环图
一.效果图展示及说明 (图一) (图二) 附注说明: 1. 图例都是DAG有向无环图的展现效果.两张图的区别为第二张图包含了多个分段关系.放置展示图片效果主要是为了说明该例子支持多段关系的展现(当前也 ...