`
momoliu
  • 浏览: 24405 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

JVM内存白皮书

    博客分类:
  • jvm
 
阅读更多

 JVM内存白皮书的翻译内容,结合了摘抄的内容,希望自己对JVM的内存和垃圾回收机制有更深入的理解。

资料来源:http://chaoticjava.com/posts/parallel-and-concurrent-garbage-collectors/

 

垃圾回收器主要负责找到并释放未被引用的对象。

所希望的垃圾回收器的特性

安全、高效:不会发生错误的回收,不会使得应用出现明显的卡顿现象

对碎片的控制:消除碎片的方法也称为compaction

 

现在的GC都使用了代回收策略,所谓代回收,指的是内存被划分为generation,不同的generation存储不同年龄的对象。使用比较广泛的是两代划分:年轻代和老年代。

这个想法的基础就是弱年代假设

   1.大部分被分配的对象很早就死了;

     2. 极少有从老年到少年的对象。

因为Java中绝大部分都是周期很短的对象,这些对象会初始存放在年轻代,年轻代的内存空间较小,且回收很频繁;而对于生命周期很长的对象则放在老年代,老年代的内存空间很大,且不经常回收,回收的耗时也会比较长。针对在不同的代中可以使用特定的垃圾回收算法。

J2SE 5.0 HotSpot JVM中的GC

内存被划分为了3代:年轻代、老年代和永久代。大部分对象初始分配在年轻代。老年代包含一些已经活了几个年轻代的对象,一些比较大的对象也可能直接分配在老年代。永久代存放的主要存放加载的Class类级对象如class本身,methodfield等等,默认的空间大小4M。

年轻代包含一个Eden2survivorfrom,to)空间。大部分的对喜爱那个直接分配在Eden。而survivor主要存放已经生存了超过至少一个代周期的对象,survivor内的对象在被放到老年代之前,会有机会被销毁。在任意时刻,survivor中必有一个用来存储,一个是空的。

垃圾回收类型

当年轻代被填满时,将执行年轻代回收(也称为minor回收);

当老年代或永久代被填满后,full collection(也成为major回收)将会被执行。这种情况下,是所有的代都会被回收。一般来说,会先回收年轻代,然后回收老年代和永久代(在特定的代会使用特定的回收策略),如果支持压缩,每个代各自完成压缩。

有时候由于要先回收年轻代,而老年代过满,而无法接受从年轻代传过来的对象。在这种情况下,除了CMS回收器,年轻代的回收算法将不会执行。老年代的回收算法将在整个堆上应用。(CMS算法会尽力避免发生这种情况

 为对象快速分配内存

在单线程情况下,只需要根据堆当前已使用内存数量的指针即可快速为对象分配内存。

在多线程情况下,这种分配方式就存在很大的性能问题。因此jvm使用了Thread Local Allocaiton BufferS机制,为每个线程分配了属于自己的buffer

 串行回收器

 在串行回收中,年轻代和老年代都是串行回收的,执行的是stop-the-world形式,也就是当回收发生的时候,应用执行就会被中止。

年轻代回收(使用串行回收器)

Eden区域的活跃对象将被复制到一开始为空的survivor(标为to)区,除了一些特别大的数据就会直接移到老年代。在另一个survivor(标为from)的对象也将被复制到这个survivorNote:如果to满了,无论edenfrom中的对象活了多久,都会直接放到老年代。在Edenfrom中的活跃对象被移走后,剩下的就是垃圾对象了,如下图的x



 

 

 

 

在一次年轻代被回收完成后,eden和之前被占用的from就会被清空。如下图



 

老年代回收(使用串行回收器)

 使用串行回收器,老年代和永久区通过mark-sweep-compact回收算法进行回收。在标记阶段,回收器将标识出活的对象。在清除阶段,收集器会在代上扫,识别出垃圾。然后收集器将活的对象全部移动到老年代的开始处,如下图

    

 

 

 

           一般在单机上,对应用暂停时间没有高要求的客户机。在一般非服务器上的jvm都是使用的串行收集器,同样可以显示的要求使用串行回收器,-XX:+UseSerialGC

并行收集器

          年轻代(使用并行收集器)

           并行的收集器使用的收集算法和串行收集器的并行版本,但因为并行收集器更好的利用了多个cpu,使得应用被迫暂停的时间大大缩短。

       

        具体的技术细节如下:

       

 

老年代(使用并行收集器)

和串行收集器相同也是使用了串行的mark-sweep-compact的收集方式。

 一般来说,在服务器上jvm都是自动跑的并行收集器,同样可以使用-XX:+UseParallelGC.

并行压缩收集器

它和并行收集器的一个中药的区别在于它对老年代的垃圾回收使用了新的算法。并行压缩收集器将替代并行收集器。

年轻代(使用并行压缩收集器)
使用的算法和并行收集器相同
老年代(并行压缩收集器)

 收集器使用了3阶段。1,每代在逻辑上被划分成固定大小的区域。在marking阶段,所有的活的对象被并行划分和标记。当一个对象被标记为活的时候,它所在的区域就会更新关于这个对象的大小和位置的信息。summary阶段是针对region来说的。一般来说,如果一个区域本身就存在大量的活对象,密集度很高,就无需再进行压缩。所有summary阶段首先会检查这些区域的密集度,它从最左开始扫,直到某处的右边值得压缩(即某处右边比较稀疏)为止。该处左边的部分就称为密集区域,没有对象会被移动到那里。而该处右边部分将被压缩,消除掉所有的存有死对象。summary阶段计算了并存储了每个区域的压缩点的开始位置。

在压缩阶段,利用summary阶段的数据来识别出哪个region需要被填充,线程可以独立的复制数据到这些区域里。如果想使用并行压缩收集器的话可以-XX:+UseParallelOldGC

一个具体的实现细节如下:首先将老年代划分为几个region(一般根据GC的线程数进行划分),然后并行的标记更新每个region的活跃对象信息;确定好dense prefix,也就是确定了需要压缩的区域;而且在summary阶段,收集器可以知道每个区域所剩余的空间,从而确定将哪些区域活跃对象填充到某些区域去(压缩),一般是选择右边的区域作为源区域,左边的区域作为目标区域(保持左边的密集度高于右边);由于每个thread负责各自的区域,除了作为源区域的线程不进行sweep操作外,其他的线程各自进行sweep,清除垃圾;当目标区域的thread处理好目标区域后,会立即将源区域的活跃对象填入目标区域,然后清理源区域。

  

 

 

 

 

 

并发的mark-sweep(CMS)收集器

该收集器也以低延迟收集器著称。
年轻代(使用CMS)
和其他的并行收集器相同
老年代(使用CMS)
老年代的垃圾回收一般和应用执行并发执行的。
一个CMS垃圾回收开始于一个很短的暂停,也就是初始化标记阶段,标记出了所有活的对象的初始化集合。然后在并发标记阶段,收集器将从初始化集合出发,标记出能由该集合的元素到达的对象。因为在标记阶段,应用也在运行,会不断更新引用,不是所有的活的对象都能在并发标记结束的之前被标记出来。为了处理这个问题,收集器开始了第二个暂停,叫做remark,将遍历并发标记阶段所标记的所有对象。在remark阶段结束后,所有的活的对象都可以确定已经被标记好了,因此接下来的并发sweep阶段将回收所有被标记的对象。



 

需要说明的是CMS并非是一个压缩算法,在回收后,内存空间是不连续的,cms使用空闲list来进行内存分配。它通过list来将所有的未分配空间连接,每当需要为一个对象分配空间时,需要搜索这个空闲list来找到足够大的空间进行分配。



由于CMS和应用是并发的,应用随时需要为对象分配空间,所以CMS收集器所需要的堆大小是比其他的并行收集器要大的。和其他回收器不同的是,CMS回收器在老年代满了的时候,是不会开始一个老年代的回收的。它会尽可能早的开始回收以防出现这个问题。否则的话,cms回收器就会退化到一般的回收器。CMS会根据前期的回收耗时和老年代的填满速度来计算开始回收的时间。而且,CMS会设定一个初始值,如果老年代的占有量超过了这个初始值,CMS回收器就会开始回收,这个值可以通过-XX:CMSInitiatingOccupancyFraction=N,N为老年代的总大小的百分比,默认68%
总的来说,对比于其他的并行收集器,CMS减少了老年代的暂停时间。
如果想要使用CMS,需要-XX:+UseConcMarkSweepGC;如果需要增量式的使用,则–XX:+CMSIncrementalMode
  • 大小: 50.2 KB
  • 大小: 35 KB
  • 大小: 49.3 KB
  • 大小: 37.7 KB
  • 大小: 94 KB
  • 大小: 83.6 KB
  • 大小: 55.1 KB
  • 大小: 34.9 KB
  • 大小: 29.6 KB
分享到:
评论

相关推荐

    JVM内存管理白皮书

    sun公司出版的jvm运行机制管理丛书,需要深入jvm的同学可以下载来看看

    JVM内存管理白皮书[借鉴].pdf

    JVM内存管理白皮书[借鉴].pdf

    java11-jvm白皮书.pdf

    读各类翻译的Java虚拟机原理,都被不如直接读官方的原版白皮书效果好。Java虚拟机,顾名思义,本质上是个虚拟的电脑,含有虚拟CPU、虚拟内存和...JVM白皮书是对这个电脑的CPU结构指令集、操作系统结构规则等的定义。

    java内存管理白皮书

    java虚拟机内存管理说明,适合想要深入了解jvm内存管理的开发人员。

    JAVA内存调优白皮书(IBM)

    JAVA内存调优白皮书(IBM)JAVA内存调优白皮书(IBM)JAVA内存调优白皮书(IBM)JAVA内存调优白皮书(IBM)

    内存管理白皮书(英文))

    2.take a deep look inside the JVM memory management model 3.introduce how to choose a suitable GC strategy and how to configure your JVM for your application 4.introduce the key options for JVM ...

    官方HotSpot内存管理文档

    官网HotSpot内存管理白皮书,对于jvm调优具有指导性意义

    Java内存管理机制相关资料汇总

    资源名称:Java内存管理机制相关资料汇总资源目录:【】java内存回收机制及预防【】java内存管理机制【】java内存管理白皮书【】Java虚拟机内存管理_对象和引用_空指针【】深入理解java虚拟机jvm高级行与最佳实践...

    12_尚硅谷大数据技术之Oozie.doc

    ·全程内容涵盖数据结构、设计模式、JVM内存结构等深度技术 ·企业级笔试面试题目深入源码级讲解,拒绝死记硬背 4.代码量更大、案例更丰富、更贴近实战: ·Java语言基础阶段:12720行代码,Java语言高级阶段:...

Global site tag (gtag.js) - Google Analytics