上节我们介绍了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探索之内存管理(三)的更多相关文章

  1. JVM探索之——内存管理(一)

    本系列的第一篇文章,预计本系列最后面会有两三个案例. Java与C.C++不一样Java不需要Coder进行手动内存管理,而这一切都交给JVM进行自动内存管理,这从某种程度上来说也减轻了我们Coder ...

  2. JVM探索之——内存管理(二)

    上篇文章我们介绍了JVM所管理的内存结构也就是运行时数据区(Run-Time Data Areas),现在我们将介绍JVM的内存分配与回收静态内存分配与动态内存分配 JVM的内存分配主要分为两种:静态 ...

  3. JVM介绍&自动内存管理机制

    1.介绍JVM(Java Virtual Machine,Java虚拟机) JVM是Java Virtual Machine的缩写,通常成为java虚拟机,作为Java可以进行一次编写,到处执行(Wr ...

  4. Linux内存描述之内存区域zone--Linux内存管理(三)

    1 内存管理域zone 为了支持NUMA模型,也即CPU对不同内存单元的访问时间可能不同,此时系统的物理内存被划分为几个节点(node), 一个node对应一个内存簇bank,即每个内存簇被认为是一个 ...

  5. Linux内存描述之内存区域zone–Linux内存管理(三)

    服务器体系与共享存储器架构 日期 内核版本 架构 作者 GitHub CSDN 2016-06-14 Linux-4.7 X86 & arm gatieme LinuxDeviceDriver ...

  6. PHP内核探索:内存管理开篇

    内存是计算机非常关键的部件之一,是暂时存储程序以及数据的空间,CPU只有有限的寄存器可以用于存储计算数据,而大部分的数据都是存储在内存中的,程序运行都是在内存中进行的.和CPU计算能力一样, 内存也是 ...

  7. COCOS学习笔记--Cocod2dx内存管理(三)-Coco2d-x内存执行原理

    通过上两篇博客.我们对Cocos引用计数和Ref类.PoolManager类以及AutoreleasePool类已有所了解,那么接下来就通过举栗子来进一步看看Coco2d-x内存执行原理是如何的. / ...

  8. Java Core - JVM运行时内存管理

    在读正文之前,阅读以下两篇博客学习并理解堆栈.作用域.本地方法的概念. 作用域:https://www.cnblogs.com/AlanLee/p/6627949.html 操作数栈:https:// ...

  9. jvm之自动内存管理

    一.运行时数据区 程序计数器(线程私有) 1.程序计数器占用jvm内存较小,主要用来记录当前线程所执行的字节码的位置,因为jvm的多线程都是通过cpu对线程进行来回切换,所以在某个确定的时间cpu只会 ...

随机推荐

  1. 第 17 章 CSS 边框与背景[下]

    学习要点: 1.设置背景 主讲教师:李炎恢 本章主要探讨 HTML5 中 CSS 边框和背景,通过边框和背景的样式设置,给元素增加更丰富的外观. 一.设置背景 盒模型的尺寸可以通过两种方式实现可见性, ...

  2. 读书笔记系列之java性能优化权威指南 一 第一章

    主题:java性能优化权威指南 pdf 版本:英文版 Java Performance Tuning 忽略:(0~24页)Performance+Acknowledge 1.Strategies, A ...

  3. Oracle的AWR报告分析

    * 定义:awr报告是oracle 10g下提供的一种性能收集和分析工具,它能提供一个时间段内整个系统资源使用情况的报告,通过这个报告,我们就可以了解一个系统的整个运行情况,这就像一个人全面的体检报告 ...

  4. selenium webdriver读取excel进行数据驱动测试

    最近做自动化需要从文件读取数据做参数化,网上发现一个不错的解决方案. 准备:新建一个excel文件,文件名为测试类名,sheet名为测试方法名         excel第一行为标题,从第二行开始为测 ...

  5. WinForm 窗体应用程序(初步)之一

    学习制作一个WinForm程序,有两样东西是需要首先掌握的.第一部分,我们称之为属性面板.无论是窗体还是控件,都有着自己的属性面板.第二部分,则是我们称之为控件的东西. 我们先来讨论一下属性面板.新建 ...

  6. Spring IoC源码解决——工具篇Eclipse

    题外话 对于Spring框架,平时都是点到为止,停留在会用的程度.一直以来都想深入学习下,刚好最近看到<Spring源码深度解析>,所以想随着书本深入学习一下. 如果用Maven 如果使用 ...

  7. CentOS系统Kernel panic - not syncing: Attempted to kill init

    结果启动虚拟机出现如下问题: Kernel panic - not syncing: Attempted to kill init     解决方法: 系统启动的时候,按下'e'键进入grub编辑界面 ...

  8. 充满想象力的 JavaScript 物理和重力实验

    在这个列表中挑选了9个物理和重力实验,用来展示 Javascript 的强大.几年前,所有这些实验都必须使用 Java 或 Flash 才能做.在下面这些惊人的例子中,就个人而言,我比较喜欢仿真布料的 ...

  9. Font Combiner – 自定义网页字体和图标生成工具

    Font Combiner 是一个功能丰富的 Web 字体生成工具和字体改进工具,提供字距调整.构造子集.各种提示选项和自定义字体字形组合.您可以生成您自己的自定义字体的格式和文件大小. 另外还有成千 ...

  10. 从客户端(?)中检测到有潜在危险的 Request.Path 值 的解决方案

    public ActionResult A(string title) { return Redirect("B"+((String.IsNullOrEmpty(title))?& ...