`

《分布式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类和对象** - **类**:定义了一组对象的属性和行为。 - **对象**:...

    4747 Java语言程序设计(一)

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

    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:...

Global site tag (gtag.js) - Google Analytics