`
momoliu
  • 浏览: 25169 次
  • 性别: 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 Microsystems公司出版的《JVM内存管理白皮书》中,我们可以找到关于Java虚拟机(JVM)内存管理的详细介绍和深入分析。这份文档对于想要深入了解JVM工作原理的读者来说是一份宝贵的学习资料。在这份...

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

    在《JVM内存管理白皮书》中,深入探讨了JVM如何处理内存分配、垃圾收集以及各种收集器的工作原理。以下是对该白皮书部分内容的详细解读: 1. 显式与自动内存管理: 在传统的C++等语言中,程序员需要手动进行内存...

    java11-jvm白皮书_java_govwe_

    在JVM内存模型和并发方面,Java 11引入了JEP 318(Enhanced Dependent Types for Compact Strings),这改进了字符串内存布局,减少了内存占用,从而提高了内存效率。 此外,JEP 315(JVM Constants API)为开发者...

    java11-jvm白皮书

    这份白皮书主要关注JVM的内部工作原理,包括垃圾收集、内存管理、类加载机制、性能优化等方面,是Java开发者深入理解Java运行环境的重要参考资料。 一、JVM概述 Java虚拟机(JVM)是Java平台的核心组成部分,它负责...

    JAVA内存调优白皮书(IBM)

    总的来说,《JAVA内存调优白皮书(IBM)》是Java开发者进行性能优化的重要参考资料,它帮助我们理解JVM内存的工作机制,掌握调优技巧,以提升应用的运行效率和用户体验。通过深入学习和实践,开发者可以更好地应对复杂...

    java内存管理白皮书

    内存管理是Java程序运行时不可或缺的一部分,它涉及到对象的创建、使用以及在不再使用时释放内存等操作。...对于想要深入了解JVM内存管理的开发人员来说,本文提供了一个很好的学习资源和参考资料。

    jave---白皮书

    白皮书可能包含类加载机制、字节码执行、JVM内存模型等细节。 10. **标准库API**:Java的标准库提供大量类和接口,用于开发各种应用程序。白皮书可能会介绍一些核心库,如集合、网络、XML处理等。 11. **Java EE与...

    java白皮书官方版

    3. **自动内存管理**:Java采用垃圾回收机制(Garbage Collection, GC)自动管理内存,避免了程序员手动释放内存可能导致的错误。 4. **安全性**:Java设计时高度重视安全,它有内置的安全模型,防止恶意代码对系统...

    Java白皮书

    Java白皮书首先会介绍Java的历史背景,解释其为何能在众多编程语言中脱颖而出,以及它如何通过Java虚拟机(JVM)实现平台无关性。 在语言基础部分,白皮书会涵盖Java的基本语法,如变量、数据类型、控制结构(如if...

    glassfish-ose-4.0 白皮书

    4. **性能优化**:GlassFish 4.0在性能方面进行了显著优化,包括更高效的线程池管理、内存分配策略以及对JVM的调优,这些都为高并发和大数据量的应用提供了稳定的支持。 5. **云就绪**:作为一款现代应用服务器,...

    jave白皮书

    中,我们只看到"jave白皮书",这意味着压缩包可能包含一个或多个章节,详细阐述Java的不同方面,如基础语法、类和对象、集合框架、多线程、网络编程、IO流、异常处理、反射、垃圾回收机制、JVM工作原理、Java EE企业...

    jave白皮书技术资料

    - **内存管理**:JVM负责内存的分配与回收,包括栈内存、堆内存和方法区。 - **垃圾收集**:自动进行垃圾回收,避免内存泄露,提供高效的内存管理。 3. **类加载器**: - **类的生命周期**:从加载、验证、准备...

    BEA WebLogic Server 9.0 技术白皮书(中文)

    5. **性能优化**: WebLogic Server 9.0 引入了改进的JVM(Java虚拟机)和内存管理策略,提升了运行时性能。同时,它支持JRockit JVM,提供更高级别的性能分析和调优功能。 6. **安全增强**: 除了WS-Security外,9.0...

    金蝶Apusic应用服务器 V10企业版 用户手册+技术白皮书+调优手册

    该版本的用户手册、技术白皮书以及调优手册提供了全面的技术指导和优化策略,帮助用户深入理解和充分利用此平台。 一、用户手册 AAS-V10用户手册详细介绍了如何安装、配置和管理金蝶Apusic应用服务器V10。这包括但...

    java白皮书.zip

    2. **自动内存管理**:Java通过垃圾回收机制自动处理内存,程序员无需手动释放内存,降低了内存泄漏的风险。 3. **异常处理**:Java提供了异常处理机制,通过try-catch-finally语句块来捕获和处理运行时错误,增强了...

Global site tag (gtag.js) - Google Analytics