`
ayufox
  • 浏览: 276176 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

[Java性能剖析]Sun JVM内存管理和垃圾回收

    博客分类:
  • JVM
阅读更多

       内存管理和垃圾回收是JVM非常关键的点,对Java性能的剖析而言,了解内存管理和垃圾回收的基本策略非常重要。本篇对Sun JVM 6.0的内存管理和垃圾回收做大概的描述。

      1.内存管理
      在程序运行过程当中,会创建大量的对象,这些对象,大部分是短周期的对象,小部分是长周期的对象,对于短周期的对象,需要频繁地进行垃圾回收以保证无用对象尽早被释放掉,对于长周期对象,则不需要频率垃圾回收以确保无谓地垃圾扫描检测。为解决这种矛盾,Sun JVM的内存管理采用分代的策略。
      1)年轻代(Young Gen):年轻代主要存放新创建的对象,内存大小相对会比较小,垃圾回收会比较频繁。年轻代分成1个Eden Space和2个Suvivor Space(命名为A和B)

  • 当对象在堆创建时,将进入年轻代的Eden Space。
  • 垃圾回收器进行垃圾回收时,扫描Eden Space和A Suvivor Space,如果对象仍然存活,则复制到B Suvivor Space,如果B Suvivor Space已经满,则复制 Old Gen
  • 扫描A Suvivor Space时,如果对象已经经过了几次的扫描仍然存活,JVM认为其为一个Old对象,则将其移到Old Gen。
  • 扫描完毕后,JVM将Eden Space和A Suvivor Space清空,然后交换A和B的角色(即下次垃圾回收时会扫描Eden Space和BSuvivor Space。

      我们可以看到:Young Gen垃圾回收时,采用将存活对象复制到到空的Suvivor Space的方式来确保不存在内存碎片,采用空间换时间的方式来加速内存垃圾回收。
      2)年老代(Tenured Gen):年老代主要存放JVM认为比较old的对象(经过几次的Young Gen的垃圾回收后仍然存在),内存大小相对会比较大,垃圾回收也相对没有那么频繁(譬如可能几个小时一次)。年老代主要采用压缩的方式来避免内存碎片(将存活对象移动到内存片的一边),当然,有些垃圾回收器(譬如CMS垃圾回收器)出于效率的原因,可能会不进行压缩。
      3)持久代(Perm Gen):持久代主要存放类定义、字节码和常量等很少会变更的信息,关于这块的垃圾回收策略可以参考我的另一篇BLOG《Tomcat Context reloadabled 与 OutOfMemory(PermSpace) 》。
      Class data sharing (CDS)( http://java.sun.com/j2se/1.5.0/docs/guide/vm/class-data-sharing.html)是JDK5新引入的特性,采用在虚拟机之间共享一些class定义信息(bootstrapClassLoader加载的类)的方式提速JVM的启动和内存的占用,主要用于客户端,如果需要对类进行instrutment,最好把CDS关闭。(默认情况下,JVM的server模式会关闭CDS,client模式会开启CDS)

-Xshare:off
Disable class data sharing.
-Xshare:on
Require class data sharing to be enabled. If it could not be enabled for various reasons, print an error message and exit.
-Xshare:auto
The default; enable class data sharing whenever possible.

 

       我们通过JConsole截图看看上面这几个区的显示(下图),从左到右分别是EdenSpace、A Suvivor Space、Tenured Gen、Code Cache、Perm Gen(shared-wr)、Perm Gen(shared-ro)、Perm Gen

      2.垃圾回收策略
      评估垃圾回收策略的两个重要度量是:

  • 吞吐量(Throughput ):JVM花费在垃圾回收上的时间越长,则吞吐量越低
  • 暂停时间(Pause time):JVM垃圾回收过程当中有一个暂停期,在暂停期间,应用程序不能运行,暂停时间是暂停期的长度

      非常遗憾的是,一般这两个指标是相互冲突的,改善其中一个会影响到另外一个,根据情景的不同我们决定是优先考虑吞吐量还是暂停时间,对于需要实时响应的应用,我们需要优先考虑暂停时间,对于后台运行应用,我们需要优先考虑吞吐量。
      在考察各种垃圾回收器之前,我们需要了解一下几个重要的策略

  • 并行(Parallel):并行表示使用多个线程同时进行垃圾回收的工作,此策略一般会从同时改善暂停时间和吞吐量,在有多CPU内核的服务器上,这是基本上我们要使用的策略。
  • 并发(Concurrent):并行表示垃圾回收器的一些工作(譬如垃圾标记)与应用程序同时进行,这将更进一步缩短暂停时间,需要注意的是,同时垃圾回收器的复杂性会大大增大,基本上是会降低吞吐量,
  • 内存碎片处理:有不压缩、压缩和拷贝三种策略,从空间上讲,拷贝将花费更多的内存(譬如如上内存管理的Young Gen,需要维持一个额外的Suvivor空间),从时间上来讲,不压缩会减低创建对象时的内存分配效率,在垃圾回收上,拷贝策略会比压缩策略更高效。

      Sun JVM有4垃圾回收器:

  • Serial Collector:序列垃圾回收器,垃圾回收器对Young Gen和Tenured Gen都是使用单线的垃圾回收方式,对Young Gen,会使用拷贝策略避免内存碎片,对Old Gen,会使用压缩策略避免内存碎片。基本上,在对内核的服务器上应该避免使用这种方式。在JVM启动参数中使用-XX:+UseSerialGC启用Serial Collector。
  • Parallel Collector:并发垃圾回收器,垃圾回收器对Young Gen和Tenured Gen都是使用多线程并行垃圾回收的方式,对Young Gen,会使用拷贝策略避免内存碎片,对Old Gen,会使用压缩策略避免内存碎片。在JVM启动参数中使用-XX:+UseParallelGC启用Parallel Collector。
  • Parallel Compacting Collector:并行压缩垃圾回收器,与Parallel Collector垃圾回收类似,但对Tenured Gen会使用一种更有效的垃圾回收策略,此垃圾回收器在暂停时间上会更短。在JVM启动参数中使用-XX:+UseParallelOldGC启用Parallel Compacting Collector。
  • Concurrent Mark-Sweep (CMS) Collector:并发标志清除垃圾回收器,对Young Gen会使用与Parallel Collector同样的垃圾回收策略,对Tenured Gen,垃圾回收的垃圾标志线程与应用线程同时进行,而垃圾清除则需要暂停应用线程,但暂停时间会大大缩减,需要注意的是,由于垃圾回收过程更加复杂,会降低总体的吞吐量。

 

6
3
分享到:
评论
10 楼 zoutuo 2013-06-30  
前辈可否告知其中的“吞吐量”指的是什么?谢谢!
9 楼 beritha 2013-06-06  
cobrano1 写道
Concurrent Mark-Sweep (CMS) Collector 最后一种策略没有写上如何配置参数

-XX:+UseConcMarkSweepGC
8 楼 cobrano1 2012-06-20  
Concurrent Mark-Sweep (CMS) Collector 最后一种策略没有写上如何配置参数
7 楼 ayufox 2010-05-29  
ahuaxuan 写道

但是有一个点:
ayufox 写道

如果B Suvivor Space已经满,则复制 Old Gen
这句话你写的很模糊
我的理解是:
1.存活对象放不进B, 那么会选择存活对象中, 拷贝次数较高的搬移到old
2.存活对象大于B空间, 存活对象将被马上搬移到old

确实写地不够清晰,不够严谨
6 楼 ahuaxuan 2010-05-29  
ayufox 写道
ahuaxuan 写道
ayufox 写道
垃圾回收器进行垃圾回收时,扫描Eden Space和A Suvivor Space,如果对象仍然存活,则复制到B Suvivor Space,如果B Suvivor Space已经满,则复制 Old Gen
这个不一定, 由于A和B有一个总是为空, 所以扫描的时候有时候是扫描eden和A,下一次扫描就是eden和B.
扫描eden和A的时候, 存活的对象会搬到B, 扫描eden和B的时候, 存活的对象会搬到A.
当某个对象被如此拷贝的次数达到一定的量的时候,该对象才会搬到old

呵呵,你对我的理解好象有问题,在这里,B(先假设是空的)并不一定能够满足存放所有存活的Eden Space和A Suvivor Space的对象,另外,你这里的描述同样可以见我下面的说明
ayufox 写道
扫描完毕后,JVM将Eden Space和A Suvivor Space清空,然后交换A和B的角色(即下次垃圾回收时会扫描Eden Space和BSuvivor Space。


恩,对的, 一样的意思

但是有一个点:
ayufox 写道

如果B Suvivor Space已经满,则复制 Old Gen
这句话你写的很模糊
我的理解是:
1.存活对象放不进B, 那么会选择存活对象中, 拷贝次数较高的搬移到old
2.存活对象大于B空间, 存活对象将被马上搬移到old

5 楼 ayufox 2010-05-29  
ahuaxuan 写道
找到了, 呵呵
-XX:MaxTenuringThreshold=<value>
This switch determines how much the objects may age in the young generation before getting promoted to the older generation. The default value is 31. For a big enough young generation and "survivor space", the long-lived objects may be copied up to 31 times between the survivor spaces before they are finally promoted to the old generation.

4 楼 ayufox 2010-05-29  
ahuaxuan 写道
ayufox 写道
垃圾回收器进行垃圾回收时,扫描Eden Space和A Suvivor Space,如果对象仍然存活,则复制到B Suvivor Space,如果B Suvivor Space已经满,则复制 Old Gen
这个不一定, 由于A和B有一个总是为空, 所以扫描的时候有时候是扫描eden和A,下一次扫描就是eden和B.
扫描eden和A的时候, 存活的对象会搬到B, 扫描eden和B的时候, 存活的对象会搬到A.
当某个对象被如此拷贝的次数达到一定的量的时候,该对象才会搬到old

呵呵,你对我的理解好象有问题,在这里,B(先假设是空的)并不一定能够满足存放所有存活的Eden Space和A Suvivor Space的对象,另外,你这里的描述同样可以见我下面的说明
ayufox 写道
扫描完毕后,JVM将Eden Space和A Suvivor Space清空,然后交换A和B的角色(即下次垃圾回收时会扫描Eden Space和BSuvivor Space。

3 楼 ahuaxuan 2010-05-29  
找到了, 呵呵
-XX:MaxTenuringThreshold=<value>
This switch determines how much the objects may age in the young generation before getting promoted to the older generation. The default value is 31. For a big enough young generation and "survivor space", the long-lived objects may be copied up to 31 times between the survivor spaces before they are finally promoted to the old generation.
2 楼 ahuaxuan 2010-05-29  
ayufox 写道
垃圾回收器进行垃圾回收时,扫描Eden Space和A Suvivor Space,如果对象仍然存活,则复制到B Suvivor Space,如果B Suvivor Space已经满,则复制 Old Gen
这个不一定, 由于A和B有一个总是为空, 所以扫描的时候有时候是扫描eden和A,下一次扫描就是eden和B.
扫描eden和A的时候, 存活的对象会搬到B, 扫描eden和B的时候, 存活的对象会搬到A.
当某个对象被如此拷贝的次数达到一定的量的时候,该对象才会搬到old
1 楼 ahuaxuan 2010-05-29  

ayufox 写道
扫描A Suvivor Space时,如果对象已经经过了几次的扫描仍然存活,JVM认为其为一个Old对象,则将其移到Old Gen。
这里的次数是可以调整的, 默认的好像是31次

相关推荐

    Sun JVM原理与内存管理

    Sun JDK 1.6 的垃圾收集器(GC)是其内存管理的关键组成部分,它负责自动地回收不再使用的对象所占用的内存。本文将详细介绍Sun JDK 1.6 GC的工作原理、内存管理机制以及调优技巧。 #### 二、为什么学习GC? - **...

    JVM历史发展和内存回收笔记

    Java虚拟机(JVM)是Java程序运行的基础,它的...开发者应根据应用的需求选择合适的JVM版本和垃圾回收策略,以实现最佳的系统性能。通过持续学习和实践,开发者可以更好地掌握JVM的奥秘,提升软件开发和维护的质量。

    JVM内容管理和垃圾回收

    **JVM内容管理和垃圾回收** Java虚拟机(JVM)是Java编程语言的核心组成部分,它为Java应用程序提供了运行环境。JVM的主要职责包括类加载、内存管理、执行字节码以及垃圾回收。以下是对这些核心功能的详细阐述: 1...

    Java高级面试JVM虚拟机、内存结构、垃圾回收机制

    面试中,深入理解JVM的工作原理,特别是内存管理和垃圾回收机制,对于Java工程师来说至关重要。能够分析和调优JVM参数,解决内存溢出、性能瓶颈等问题,是高级工程师必备的能力。此外,了解不同JVM实现之间的差异和...

    Java 虚拟机JVM内存模型

    通过以上对JVM内存模型和垃圾收集策略的分析,可以看出JVM内存管理的复杂性以及垃圾收集机制的重要性。了解和掌握这些知识点,对于开发高性能Java应用是非常有帮助的。在实际开发过程中,合理配置JVM参数、选择合适...

    JVM深入解析(JVM specification 和Sun的JVM的内存机制)

    本文将深入探讨JVM的各个方面,包括其工作原理、内存管理和垃圾收集(GC)机制。 1. Java特性与JVM应用 Java语言的一大特性是"一次编写,到处运行",这得益于JVM的存在。JVM执行Java字节码,使得编译后的Java程序...

    从JVM的内存管理角度分析Java的GC垃圾回收机制.docx

    Java的垃圾回收(Garbage Collection,简称GC)是其内存管理的核心机制,它自动管理程序中的对象生命周期,负责回收不再使用的对象所占用的内存空间,以防止内存泄漏。GC是Java语言的一个重要特性,使得开发者无需...

    设置jvm内存的方法

    - **重要性**: 合适的初始内存大小有助于减少垃圾回收(GC)的频率,提高应用性能。 2. **-Xmx (Maximum heap size)**: - **含义**: 设置JVM的最大堆内存大小。 - **重要性**: 当应用程序使用的内存接近-Xmx指定...

    jvm垃圾回收调整.pdf

    Java虚拟机(JVM)的垃圾回收(Garbage Collection, GC)是Java程序性能优化的重要环节。...同时,监控JVM的垃圾回收行为,通过日志和分析工具,可以帮助识别和解决问题,从而实现更高效的JVM内存管理。

    Java虚拟机中内存管理机制.pdf

    本文主要分析了Java虚拟机的内存管理,特别是垃圾回收机制及其实现。 首先,Java虚拟机中的内存主要分为堆内存和栈内存。堆内存主要存储程序运行时创建的对象实例,而栈内存则用于存放程序中的静态或非静态方法调用...

    JVM中编译Class、内存回收、多线程原理和使用

    JVM自动进行内存分配和垃圾回收。内存分为堆(Heap)、方法区(Method Area)、栈(Stack)、本地方法栈(Native Method Stack)和程序计数器(PC Register)五大部分。堆用于存储对象实例,方法区存储类信息,栈...

    Java_GC垃圾回收调优指南

    在Java开发过程中,垃圾回收(Garbage Collection, GC)是管理内存资源的关键技术之一。合理的GC配置可以显著提高应用程序的性能和稳定性。本指南旨在帮助开发者深入理解Java GC的工作原理,并提供一系列调优策略与...

    JVM内存问题最佳实践

    - **合理配置JVM参数**:根据应用程序的实际需求合理设置堆内存和其他内存区域的大小。 - **定期进行代码审查**:查找潜在的内存泄漏源。 - **使用工具辅助检测**:定期使用内存分析工具检查应用的内存使用情况。 #...

    java内存管理白皮书

    《Java内存管理白皮书》深入探讨了Java虚拟机(JVM...不仅介绍了垃圾回收的基本原理,还详细阐述了HotSpot JVM中各种垃圾收集器的特点及适用场景,旨在帮助开发者有效管理和优化Java应用程序的内存使用,提升系统性能。

    java内存管理精彩概述

    以下是对Java内存管理的精彩概述,主要基于Sun Hotspot JVM,但请注意,不同JVM可能有不同的实现方式。 1. **Java对象在内存中的存储** Java对象在内存中的分配主要发生在堆上,这是所有类实例和数组的内存来源。...

    java内存讲解

    Java作为一种广泛使用的编程语言,其内存管理和垃圾回收机制是开发人员必须了解的核心概念之一。本文将详细探讨JVM的垃圾回收机制及其调优方法,深入分析Java内存分配原理,并讨论Java中的内存管理与内存泄露问题。 ...

    java JVM详解

    SUN JVM 提供了详细的内存管理机制,旨在优化 Java 应用程序的性能。内存管理的关键部分包括: - **Heap (堆)**:用于存储 Java 对象的实例和数组。 - **Method Area (方法区域)**:存储已加载类的信息、常量、静态...

    Sun JDK 1.6内存管理--调优篇

    《Sun JDK 1.6内存管理--调优篇》深入探讨了Java开发中的关键环节——JVM内存管理和性能优化。Sun JDK 1.6作为早期的Java开发环境,其内存管理机制对于理解现代JVM的工作原理至关重要。本文将详细解析JVM内存结构,...

    JVM详解与学习

    ### JVM详解与学习 #### Java相关 ##### 1.1 Java定义 Java 是一种广泛使用的高级编程语言,具有面向...以上内容覆盖了JVM的基础知识、内存管理和垃圾收集等方面,对于深入理解Java应用程序的运行机制非常有帮助。

Global site tag (gtag.js) - Google Analytics