`

《分布式JAVA应用 基础与实践》 第三章 3.2 JVM内存管理(四)

阅读更多

3.2.4  JVM内存状况查看方法和分析工具(1)

Java本身提供了多种丰富的方法和工具来帮助开发人员查看和分析GC及JVM内存的状况,同时开源界和商业界也有一些工具可用于查看、分析GC及 JVM内存的状况。通过这些分析,可以排查程序中内存泄露的问题及调优程序的性能。下面介绍几种常用的免费工具,其中知名的有JProfiler 等。

1. 输出GC日志

输出GC日志对于跟踪分析GC的状况来说,无疑是最直接地分析内存回收状况的方法,只是GC日志输出后需要人为地进行分析,以判断GC的状况。

JVM支持将日志输出到控制台或指定的文件中,方法有如下几种。

输出到控制台

在JVM的启动参数中加入-XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationStoppedTime,按照参数的顺序分别输出GC的简要信息,GC的详细信息、GC的时间信息及GC 造成的应用暂停的时间。

输出到指定的文件

在1中的jvm启动参数中再增加-Xloggc: gc.log可指定将gc的信息输出到gc.log中。

可用于GC跟踪分析的参数还有-verbose:gc、-XX:+PrintTenuringDistribution等。

2. GC Portal

将GC日志输出固然有一定的作用,但如果要靠人为进行分析,还是相当复杂的。因此Sun提供了一个GC Portal来帮助分析这些GC日志,并生成相关的图形化的报表,GC Portal部署起来会有些麻烦,它需要运行在老版本的Tomcat上,同时需要数据库,部署完毕后通过上传日志文件的方式即可完成GC日志的分析,此 GC日志输出的JVM参数为:-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps [-Xloggc:文件名],在上传日志时GC Portal的选项里只有jdk 1.2或jdk 1.2-1.4的版本。虽然经过测试,JDK 6的日志也是可以分析出来的,但它的限制在于仅支持5MB的gc日志的分析,GC Portal可提供吞吐量的分析、耗费的CPU的时间、造成的应用暂停的时间、每秒从新生代转化到旧生代的数量、minor GC的状况及Full GC的状况等,如图3.17所示。

 
(点击查看大图)图3.17  GCPortal示例

GC Portal中还有一个很有用的部分是提供调整GC参数的预测,例如可以选择给young size增加20%的空间。GC Portal会根据当前的日志信息来评估在调整参数后的运行效果,不一定很准确,但毕竟能带来一些参考意义。

3. JConsole

JConsole可以图形化查看JVM中内存的变化状况,JConsole是JDK 5及以上版本中自带的工具,位于JDK的bin目录下,运行时直接运行JConsole.exe或JConsole.sh(要求支持图形界面)。在本地的 Tab页上看到运行了java的pid,双击即可查看相应进程的JVM状况,同时,JConsole也支持查看远程的JVM的运行状况,具体可参见 JConsole的User Guide。

JConsole中显示了JVM中很多的信息:内存、线程、类和MBean等,在打开JConsole的内存Tab页后,可看到JVM内存部分的运行状况。这对于分析内存是否有溢出及GC的效果更加直接明了,JConsole的运行效果如图3.18所示。

 
(点击查看大图)图3.18  JConsole运行效果

 

 

4. JVisualVM

JVisualVM是JDK 6 update 7之后推出的一个工具,它类似于JProfiler的工具,基于此工具可查看内存的消耗情况、线程的执行状况及程序中消耗CPU、内存的动作。

在内存分析上,JVisualVM的最大好处是可通过安装VisualGC插件来分析GC趋势、内存消耗详细状况。

VisualGC的运行如图3.19所示。

 
(点击查看大图)图3.19  VisualGC运行效果

从图3.19中可看到各区的内存消耗状况及GC Time的图表,其提供的Histogram视图对于调优也有很大帮助。

基于JVisualVM的Profiler中的Memory还可查看对象占用内存的状况,如图3.20所示。

4. JMap

JMap是JDK中自带的一个用于分析JVM内存状况的工具,位于JDK的bin目录下。使用JMap可查看目前JVM中各个代的内存状况、JVM中对象的内存的占用状况,以及导出整个JVM中的内存信息。

 
(点击查看大图)图3.20  JVisualVM Memory Profiler图示

查看JVM中各个代的内存状况

在linux上执行jmap -heap [pid],就可查看整个JVM中内存的状况,看到的信息类似如下(和JDK版本、GC策略有关):

    using thread-local object allocation. Parallel GC with 8 thread(s) Heap Configuration: MinHeapFreeRatio = 40 MaxHeapFreeRatio = 70 MaxHeapSize = 1610612736 (1536.0MB) NewSize = 524288000 (500.0MB) MaxNewSize = 524288000 (500.0MB) OldSize = 4194304 (4.0MB) NewRatio = 8 SurvivorRatio = 8 PermSize = 100663296 (96.0MB) MaxPermSize = 268435456 (256.0MB) Heap Usage: PS Young Generation Eden Space: capacity = 430702592 (410.75MB) used = 324439936 (309.4100341796875MB) free = 106262656 (101.3399658203125MB) 75.32806675098904% used From Space: capacity = 46333952 (44.1875MB) used = 13016424 (12.413429260253906MB) free = 33317528 (31.774070739746094MB) 28.092626331550566% used To Space: capacity = 46792704 (44.625MB) used = 0 (0.0MB) free = 46792704 (44.625MB) 0.0% used PS Old Generation capacity = 1086324736 (1036.0MB) used = 945707880 (901.8973159790039MB) free = 140616856 (134.1026840209961MB) 87.05572548059884% used PS Perm Generation capacity = 100663296 (96.0MB) used = 46349592 (44.202415466308594MB) free = 54313704 (51.797584533691406MB) 46.044182777404785% used

 

从以上信息中可看出JVM堆的配置信息,如NewSize、NewRatio、SurvivorRatio等;JVM堆的使用情况,新生代中的Eden Space、From Space、To Space的使用情况,旧生代和持久代的使用情况。

要注意的是在使用CMS GC的情况下,jmap -heap的执行有可能会导致Java进程被挂起。

JVM中对象的内存的占用情况

在查看JVM内存状况时,除了要知道每个代的占用情况外,很多时候更要知道其中各个对象占用的内存大小,这样便于分析对象的内存占用情况,在分析OutOfMemory的场景中尤其适用。

输入jmap -histo [pid]即可查看jvm堆中对象的详细占用情况,如图3.21所示。

 
图3.21  jmap -histo运行效果

输出内容按照占用空间的大小排序,例如上面的[C,表示char类型的对象在jvm中总共有243 707个实例,占用了501 638 784 bytes的空间。

导出整个JVM中的内存信息

通过以上方法能查看到JVM中对象内存的占用情况,但很多时候还要知道这个对象到底是谁创建的。例如上面显示出来的[C,只知道它占用了那么多的空 间,但不知道是什么对象创建出的[C,于是jmap提供了导出整个jvm中的内存信息的支持。基于一些jvm内存的分析工具,例如sun JDK 6中的jhat、Eclipse Memory Analyzer,可以分析jvm中内存的详细信息,例如[C是哪些对象创建的。

执行如下命令即可导出整个jvm中的内存信息:

  1. jmap -dump:format = b , file =文件名 [pid]

5. JHat

JHat是Sun JDK 6及以上版本中自带的一个用于分析jvm堆dump文件的工具,基于此工具可分析jvm heap中对象的内存占用状况、引用关系等。

执行如下命令分析jvm堆的dump文件:

  1. jhat -J-Xmx1024M [file]

执行后等待console中输出Started HTTP server on port 7000,看到后就可以通过浏览器访问http://ip:7000 了,此页面默认为按package分类显示系统中所有的对象实例。在页面的最下端有Other Queries导航,其中有显示jvm中对象实例个数的链接、有显示jvm中对象大小的链接等,点击显示jvm中对象大小的链接,得到的结果如图3.22所示。

 
图3.22  jhat运行效果

点击图3.22中的class [C,可以看到有哪些对象实例引用了这个对象,或者创建了这个对象,jhat在分析大的堆dump文件时表现不好,速度很慢。

6. JStat

JStat是Sun JDK自带的一个统计分析JVM运行状况的工具,位于JDK的bin目录下,除了可用于分析GC的状况外,还可用于分析编译的状况、class加载的状况等。

JStat用于GC分析的参数有:-gc、-gccapacity、-gccause、-gcnew、-gcnewcapacity、 -gcold、-gcoldcapacity、-gcpermcapacity、-gcutil。常用的为-gcutil。通过-gcutil可按一定频 率查看jvm中各代的空间的占用情况、minor GC的次数、消耗的时间、full GC的次数及消耗的时间的统计,执行jstat -gcutil [pid] [interval],可看到类似如下的输出信息:

    S0 S1 E O P YGC YGCT FGC FGCT GCT 0.00 74.24 96.73 73.43 46.05 17808 382.335 208 315.197 697.533 45.37 0.00 28.12 74.97 46.05 17809 382.370 208 315.197 697.568

其中S0、S1就是Survivor空间的使用率,E表示Eden空间的使用率,O表示旧生代空间的使用率,P表示持久代的使用率,YGC表示 minor GC的执行次数,YGCT表示minor GC执行消耗的时间,FGC表示Full GC的执行次数,FGCT表示Full GC执行消耗的时间,GCT表示Minor GC+Full GC执行消耗的时间。

 

7. Eclipse Memory Analyzer

Eclipse Memory Analyzer是Eclipse提供的一个用于分析jvm堆dump文件的插件,借助这个插件可查看对象的内存占用状况、引用关系、分析内存泄露等。

Eclipse Memory Analyzer(MAT)的网站为:http://www.eclipse.org/mat/ ,在eclipse中可以直接远程安装此插件。不过由于此插件在分析堆dump文件时比较耗内存,因此在分析前最好先将eclipse的jvm的内存设置大一点,MAT分析dump文件后的对象占用内存及引用关系如图3.23所示。

相对而言MAT功能比jhat强大很多,分析的速度也快一些,因此,如果要分析jvm堆dumap文件,首选推荐的是MAT。

在进行JVM内存状况分析时,通常要关注的主要有GC的趋势、内存的具体消耗状况。

GC趋势对于可图形界面连到需查看GC状况的机器的情况而言,VisualVM是常用的选择;对于不能采用图形界面方式的,输出GC日志 及采用jstat命令直接分析是常用的选择。

在查找内存是程序中的什么对象占用时,需要分析内存的具体消耗状况,对于有图形界面可用的情况,VisualVM是常用的选择;对于不能采用图形界面方式的,可通过jmap dump生成文件后,再通过MAT进行分析是常用的选择。

 
(点击查看大图)图3.23  MAT运行效果

 

 

 

分享到:
评论

相关推荐

    构建高性能的大型分布式java应用

    #### 第三章:深入理解JVM **3.1 JVM类加载机制** JVM的类加载机制涉及到类的生命周期管理,主要包括加载、验证、准备、解析和初始化等阶段。类加载器负责从文件系统或其他来源加载字节码到JVM中。 **3.2 JVM内存...

    java基础知识技术

    Java的设计初衷是为了满足分布式计算的需求,特别是互联网的应用。Java语言的主要特点包括: - **平台独立性**:Java代码可以在任何安装了Java虚拟机(JVM)的平台上运行,这得益于其“一次编写,到处运行”的设计...

    JAVA基础入门教程

    Java语言起源于Sun Microsystems公司的Green项目,最初的目的是为了开发一套适用于家用电器的分布式代码系统,以便实现设备间的互联与控制。起初项目团队考虑使用C++作为开发语言,但由于C++过于复杂且安全性不足,...

    [网盘]大型网站系统与java中间件实践 pdf下载 高清完整版

    根据提供的文件信息,本文将围绕“大型网站系统与Java中间件实践”这一主题进行深入探讨。主要内容包括:大型网站系统的架构特点、Java中间件的概念及其在大型网站中的应用实践。 ### 一、大型网站系统概述 #### ...

    java2参考大全(第四版)

    ### Java2参考大全(第四版)关键知识点概览 #### 1. Java的起源与背景 **1.1 Java的由来** Java语言的历史和发展背景是理解其特性和设计理念的关键。Java是在C++的基础上发展起来的,同时也继承了C语言的一些...

    Java2参考大全(第四版)

    - **Android应用开发**:Java是Android平台的官方开发语言之一,拥有庞大的开发者社区和丰富的第三方库支持。 **3.3 大数据处理** - **分布式计算**:Java因其良好的性能和稳定性,在大数据处理和分布式计算领域也...

    java习题参考答案

    ### Java习题参考答案知识点解析 #### 一、Java的特点 **1.1 简单性** - **特点说明**: Java设计时...以上知识点涵盖了Java语言的基础特性和编程实践中的重要概念,有助于读者更好地理解和掌握Java编程的核心要点。

    Java基础教程

    - **安全性**:Java拥有严格的访问控制机制和内存管理机制,能有效防止恶意代码的攻击。 - **自动垃圾回收**:Java具有自动垃圾回收机制,可以自动释放不再使用的内存空间,简化了程序员的工作。 **3.2 Java程序...

    04747 Java程序设计(一) 自考 考点 大纲(自己总结)

    #### 第三章:面向对象编程基础 **3.1 面向对象的基本概念** - 面向对象编程(OOP)是Java的核心特性之一,主要包括封装、继承和多态。 **3.2 Java类和对象** - **类**:定义了一组对象的属性和行为。 - **对象**:...

    JAVASE基础_课堂笔记-V2.docx

    - **API丰富**:Java拥有大量的标准库和第三方库,支持各种应用场景。 - **社区活跃**:庞大的开发者社区为学习者提供大量教程和帮助文档。 **3.2 跨平台性** - Java的跨平台特性使其成为开发多平台应用的理想选择...

    Java从入门到精通-目录

    #### 第3章 Java语言基础 ##### 3.1 Java主类结构 - **3.1.1 包声明**:包是用来组织类的一种方式,帮助开发者更好地管理类和接口。 - **3.1.2 声明成员变量和局部变量**:成员变量是类的属性,局部变量是在方法...

    4747 Java语言程序设计(一)

    #### 第三章 面向对象编程基础 **3.1 面向对象技术及其优点** - **面向对象技术**:一种软件开发方法论,基于对象的概念组织程序。 - **优点**: - 提高代码复用性。 - 提升代码可维护性。 - 更好地模拟现实...

    JAVA课后习题答案

    #### 第3章 Java语言基础 **3.1 变量名合法性判断:** - **合法的变量名**:`$UstatenewsAddMyNum_B2`、`变量1addMyNumabc数int` - **非法的变量名**:`A=b`、`byte3`、`ABC'abc'`、`3.146`、`(0xab4`、`(3e1k*j...

    JavaEE_tutorialFromOracle

    此外,还可以通过编写自定义模块或利用现有的第三方组件来增强其能力。 **5.2 定制化** 开发者可以根据具体需求对Oracle Application Server 10g进行定制,包括修改默认行为、增加新的功能特性等。 #### 六、案例...

    JAVA基础教程

    #### 第三部分:Java程序应用 **3.1 JAVA多线程机制** - **多线程**:并发执行多个任务。 - **实现方式**:继承`Thread`类或实现`Runnable`接口。 - 示例: ```java public class MyThread implements Runnable...

    websphere 文档

    - **兼容性提升**:增强了与其他 IBM 产品及第三方软件的集成能力。 #### 三、WAS 系统管理概览 ##### 3.1 WAS 配置和管理架构 WAS V8.5 支持两种主要的管理架构:独立服务器环境和分布式环境。每种架构都有其...

    AKKA (java) 精讲

    Akka 的设计考虑到了 Java 内存模型的影响,确保了 Actor 的线程安全性和内存一致性。 ##### 2.8 Message Delivery Reliability Akka 支持可靠的消息传递机制,确保消息不会丢失或重复发送。 ##### 2.9 ...

    Java入门学习笔记

    - **分布式:** Java提供了强大的网络功能,使得开发分布式应用变得容易。 - **健壮性:** Java设计了许多机制来提高程序的健壮性和可靠性,如自动垃圾回收。 - **安全性:** Java具有严格的安全控制,可以在网络...

    Java经典入门教程pdf完整版

    3.2:Java是一种运行平台 Java本身提供Java软件所需要的运行环境,Java应用可运行在安装了JRE(Java Runtime environment)的机器上,所以我们说Java是一个运行平台。 JRE: Java Runtime Environment,Java运行环境。 4:...

    JINI核心技术

    第3章 Jini模型 31 3.1 Jini设计的中心 31 3.1.1 简明性 31 3.1.2 可靠性 31 3.1.3 可伸缩性 32 3.2 设备不可知论 33 3.3 Jini不是什么 33 3.3.1 Jini不是名字服务器 33 3.3.2 Jini不是JavaBeans 34 3.3.3 Jini不是...

Global site tag (gtag.js) - Google Analytics