Java 内存查看与分析

转载自   Java 内存查看与分析

  1:gc日志输出

    在jvm启动参数中加入 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimestamps -XX:+PrintGCApplicationStopedTime,jvm将会按照这些参数顺序输出gc概要信息,详细信息,gc时间信息,gc造成的应用暂停时间。如果在刚才的参数后面加入参数 -Xloggc:文件路径,gc信息将会输出到指定的文件中。其他参数还有

    -verbose:gc和-XX:+PrintTenuringDistribution等。

 

    2:jconsole

    jconsole是jdk自带的一个内存分析工具,它提供了图形界面。可以查看到被监控的jvm的内存信息,线程信息,类加载信息,MBean信息。

    jconsole位于jdk目录下的bin目录,在windows下是jconsole.exe,在unix和linux下是jconsole.sh,jconsole可以监控本地应用,也可以监控远程应用。 要监控本地应用,执行jconsole pid,pid就是运行的java进程id,如果不带上pid参数,则执行jconsole命令后,会看到一个对话框弹出,上面列出了本地的java进程,可以选择一个进行监控。如果要远程监控,则要在远程服务器的jvm参数里加入一些东西,因为jconsole的远程监控基于jmx的,关于jconsole详细用法,请见专门介绍jconsle的文章,我也会在博客里专门详细介绍jconsole。

    3:jviusalvm

    在JDK6 update 7之后,jdk推出了另外一个工具:jvisualvm,java可视化虚拟机,它不但提供了jconsole类似的功能,还提供了jvm内存和cpu实时诊断,还有手动dump出jvm内存情况,手动执行gc。

    和jconsole一样,运行jviusalvm,在jdk的bin目录下执行jviusalvm,windows下是jviusalvm.exe,linux和unix下是jviusalvm.sh。

 

    4:jmap

    jmap是jdk自带的jvm内存分析的工具,位于jdk的bin目录。jdk1.6中jmap命令用法:

    Usage:

    jmap -histo <pid>

    (to connect to running process and print histogram of java object heap

    jmap -dump:<dump-options> <pid>

    (to connect to running process and dump java heap)

    dump-options:

    format=b     binary default

    file=<file>  dump heap to <file>

    Example:       jmap -dump:format=b,file=heap.bin <pid>

    jmap -histo <pid>在屏幕上显示出指定pid的jvm内存状况。以我本机为例,执行该命令,屏幕显示:

    num     #instances         #bytes  class name

    ----------------------------------------------

    1:         24206        2791864  <constMethodKlass>

    2:         22371        2145216  [C

    3:         24206        1940648  <methodKlass>

    4:          1951        1364496  <constantPoolKlass>

    5:         26543        1282560  <symbolKlass>

    6:          6377        1081744  [B

    7:          1793         909688  <constantPoolCacheKlass>

    8:          1471         614624  <instanceKlassKlass>

    9:         14581         548336  [Ljava.lang.Object;

    10:          3863         513640  [I

    11:         20677         496248  java.lang.String

    12:          3621         312776  [Ljava.util.HashMap$Entry;

    13:          3335         266800  java.lang.reflect.Method

    14:          8256         264192  java.io.ObjectStreamClass$WeakClassKey

    15:          7066         226112  java.util.TreeMap$Entry

    16:          2355         173304  [S

    17:          1687         161952  java.lang.Class

    18:          2769         150112  [[I

    19:          3563         142520  java.util.HashMap

    20:          5562         133488  java.util.HashMap$Entry

    Total        239019       17140408

    为了方便查看,我删掉了一些行。从上面的信息很容易看出,#instance指的是对象数量,#bytes指的是这些对象占用的内存大小,class name指的是对象类型。

    再看jmap的dump选项,这个选项是将jvm的堆中内存信息输出到一个文件中,在我本机执行

    jmap -dump:file=c:dump.txt 340

    注意340是我本机的java进程pid,dump出来的文件比较大有10几M,而且我只是开了tomcat,跑了一个很简单的应用,且没有任何访问,可以想象,大型繁忙的服务器上,dump出来的文件该有多大。需要知道的是,dump出来的文件信息是很原始的,绝不适合人直接观看,而jmap -histo显示的内容又太简单,例如只显示某些类型的对象占用多大内存,以及这些对象的数量,但是没有更详细的信息,例如这些对象分别是由谁创建的。那这么说,dump出来的文件有什么用呢?当然有用,因为有专门分析jvm的内存dump文件的工具。

 

    5:jhat

    上面说了,有很多工具都能分析jvm的内存dump文件,jhat就是sun jdk6及以上版本自带的工具,位于jdk的bin目录,执行 jhat -J -Xmx512m [file] ,file就是dump文件路径。jhat内置一个简单的web服务器,此命令执行后,jhat在命令行里显示分析结果的访问地址,可以用-port选项指定端口,具体用法可以执行jhat -heap查看帮助信息。访问指定地址后,就能看到页面上显示的信息,比jmap -histo命令显示的丰富得多,更为详细。

 

    6:eclipse内存分析器

    上面说了jhat,它能分析jvm的dump文件,但是全部是文字显示,eclipse memory analyzer,是一个eclipse提供用于分析jvm 堆dump的插件,它的分析速度比jhat快,分析结果是图形界面显示,比jhat的可读性更高。其实jvisualvm也可以分析dump文件,也是有图形界面显示的。

 

    7:jstat

    如果说jmap倾向于分析jvm内存中对象信息的话,那么jsta就是倾向于分析jvm内存的gc情况。都是jvm内存分析工具,但显然,它们是从不同维度来分析的。jsat常用的参数有很多,如 -gc,-gcutil,-gccause,这些选项具体作用可查看jsat帮助信息,我经常用-gcutil,这个参数的作用不断的显示当前指定的jvm内存的垃圾收集的信息。

    我在本机执行 jstat -gcutil 340 10000,这个命令是每个10秒钟输出一次jvm的gc信息,10000指的是间隔时间为10000毫秒。屏幕上显示如下信息(我只取了第一行,因为是按的一定频率显示,所以实际执行的时候,会有很多行):

    S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT

    54.62   0.00  42.87  43.52  86.24   1792    5.093    33    7.670   12.763

    额……怎么说呢,要看懂这些信息代表什么意思,还必须对jvm的gc机制有一定的了解才行啊。其实如果对sun的 hot spot jvm的gc比较了解的人,应该很容易看懂这些信息,但是不清楚gc机制的人,有点莫名其妙,所以在这里我还是先讲讲sun的jvm的gc机制吧。说到gc,其实不仅仅只是java的概念,其实在java之前,就有很多语言有gc的概念了,gc嘛就是垃圾收集的意思,更多的是一种算法性的东西,而跟具体语言没太大关系,所以关于gc的历史,gc的主流算法我就不讲了,那扯得太远了,扯得太远了就是扯淡。sun现在的jvm,内存的管理模型是分代模型,所以gc当然是分代收集了。分代是什么意思呢?就是将对象按照生命周期分成三个层次,分别是:新生代,旧生代,持久代。对象刚开始分配的时候,大部分都在新生代,当新生代gc提交被触发后了,执行一次新生代范围内的gc,这叫minor gc,如果执行了几次minor gc后,还有对象存活,将这些对象转入旧生代,因为这些对象已经经过了组织的重重考验了哇。旧生代的gc频率会更低一些,如果旧生代执行了gc,那就是full gc,因为不是局部gc,而是全内存范围的gc,这会造成应用停顿,因为全内存收集,必须封锁内存,不许有新的对象分配到内存,持久代就是一些jvm期间,基本不会消失的对象,例如class的定义,jvm方法区信息,例如静态块。需要主要的是,新生代里又分了三个空间:eden,susvivor0,susvivor1,按字面上来理解,就是伊甸园区,幸存1区,幸存2区。新对象分配在eden区中,eden区满时,采用标记-复制算法,即检查出eden区存活 的对象,并将这些对象复制到是s0或s1中,然后清空eden区。jvm的gc说开来,不只是这么简单,例如还有串行收集,并行收集,并发收集,还有着名的火车算法,不过那说得太远了,现在对这个有大致了解就好。说到这里,再来看一下上面输出的信息:

    S0       S1       E        O          P       YGC     YGCT    FGC    FGCT     GCT

    54.62   0.00  42.87  43.52  86.24   1792    5.093    33    7.670   12.763

    S0:新生代的susvivor0区,空间使用率为5462%

    S1:新生代的susvivor1区,空间使用率为0.00%(因为还没有执行第二次minor收集)

    E:eden区,空间使用率42.87%

    O:旧生代,空间使用率43.52%

    P:持久带,空间使用率86.24%

    YGC:minor gc执行次数1792次

    YGCT:minor gc耗费的时间5.093毫秒

    FGC:full gc执行次数33

    FGCT:full gc耗费的时间7.670毫秒

    GCT:gc耗费的总时间12.763毫秒

    怎样选择工具

    上面列举的一些工具,各有利弊,其实如果在开发环境,使用什么样的工具是无所谓的,只要能得到结果就好。但是在生产环境里,却不能乱选择,因为这些工具本身就会耗费大量的系统资源,如果在一个生产服务器压力很大的时候,贸然执行这些工具,可能会造成很意外的情况。最好不要在服务器本机监控,远程监控会比较好一些,但是如果要远程监控,服务器端的启动脚本要加入一些jvm参数,例如用jconsloe远程监控tomcat或jboss等,都需要设置jvm的jmx参数,如果仅仅只是分析服务器的内存分配和gc信息,强烈推荐,先用jmap导出服务器端的jvm的堆dump文件,然后再用jhat,或者jvisualvm,或者eclipse内存分析器来分析内存状况。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/328009.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【长文干货】浅析分布式系统

测试开发者的共同关注&#xff01; 作者&#xff1a;wadehan&#xff0c;腾讯后台开发高级工程师 商业转载请联系腾讯WeTest获得授权&#xff0c;非商业转载请注明出处。 WeTest导读 我们常常会听说&#xff0c;某个互联网应用的服务器端系统多么牛逼&#xff0c;比如QQ、微信、…

hibernate配置详情2(Dept.hbm.xml)

<?xml version"1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping package"org.hibernate_on…

Spring Boot 入门 IDEA 版本 2小时学会springBoot 代码上传至gitee 或者github 事务没做出来

SpringBoot简化了xml的配置可以快速开发&#xff0c;节省很多的时间&#xff0c;springboot的配置速度更快&#xff0c;SpringMvc已经不如springboot了&#xff0c; 市面上更多的是使用spingboot这个框架了。 springboot是springmvc的升级版&#xff0c;但是2者没有必然的联…

华为云微认证答题_158人次通过华为认证考试!今年,湖北这所高校频现大动作...

从2005全国职教工作会上"校企合作"的提出&#xff0c;到2013年"产教融合"的最早出现&#xff0c;再到党的十九大&#xff0c;"产教融合、校企合作"已经逐渐成为教育新趋势。相信有许多家长和大学生都很想了解这种新的教育模式。本期推送&#xf…

在传统.NET Framework 上运行ASP.NET Core项目

新的项目我们想用ASP.NET Core来开发&#xff0c;但是苦于我们历史的遗产很多&#xff0c;比如《使用 JavaScriptService 在.NET Core 里实现DES加密算法》&#xff0c;我们要估计等到.NET Core 1.2我们才会有大部分的API&#xff0c;通过NodeJs方式有点曲线救国的味道&#xf…

JVM 调优系列之图解垃圾回收

转载自 JVM 调优系列之图解垃圾回收摘要: jvm必知系列&#xff0c;总结一些常见jvm回收机制&#xff0c;方便查阅从这篇开始我们开始探讨一些jvm调优的问题。在jvm调优中一个离不开的重点是垃圾回收&#xff0c;当垃圾回收成为系统达到更高并发量的瓶颈时&#xff0c;我们就需…

JAVA注解和反射(笔记)

注解简介 Annotation是从JDK5.0开始引入的新技术). Annotation的作用 : 不是程序本身(可以对程序作出解释.(这一点和注释(comment)没什么区别)可以被其他程序(比如:编译器等)读取. Annotation的格式: 注解是以"注释名"在代码中存在的, 还可以添加一些参数值,例如:S…

车提示检测轮胎气压_水淹车估价中心_辽宁中车检

首页 > 新闻中心发布时间&#xff1a;2021-01-02 00:57:13 导读&#xff1a;辽宁中车检为您提供水淹车估价中心的相关知识与详情&#xff1a;在行车过程中,汽车受到振动,可能会引起前照灯部件的安装位置发生变动,从而改变光束的正确照射方向.同时,灯泡在使用过程中会逐步老化…

.NET Core中间件的注册和管道的构建(3) ---- 使用Map/MapWhen扩展方法

0x00 为什么需要Map&#xff08;MapWhen&#xff09;扩展 如果业务逻辑比较简单的话&#xff0c;一条主管道就够了&#xff0c;确实用不到Map。不过当业务逻辑比较复杂的时候&#xff0c;有时候我们可能希望根据情况的不同使用特殊的一组中间件来处理HttpContext。这种情况下如…

2小时学习Spring Boot 2019版本 代码一样推送至github上面去

简介&#xff1a;《2小时学习Spring Boot》后续进阶课程&#xff0c;主要讲述了Spring Boot针对Web方面的相关技巧 讲师实战课程《Spring Boot微信点餐系统》 http://coding.imooc.com/class/117.html 《Spring Cloud微服务实战》 http://coding.imooc.com/class/187.html 均已…

认识JVM--第一篇-对象分配&回收算法

转载自 认识JVM--第一篇-对象分配&回收算法本来标题党想写成《深入JVM》&#xff0c;不过不太敢写&#xff0c;我想一小篇博客我想还不足以说明JVM&#xff0c;在本文中&#xff0c;会就我所知给大家介绍JVM的很多内部知识&#xff0c;概念会相对较粗&#xff0c;因为太细…

JAVASE阶段流程图

转载于https://blog.csdn.net/czc514/article/details/106057366

hibernate配置详情3(Dept)

package org.hibernate_one.entity;import java.io.Serializable;/** 部门实体类* 符合javabean规范* 1.公共类* 2.具有公共的无参的构造方法* 3.私有属性* 4.getter setter方法* 5.实现序列化接口Serializable java.io*/public class Dept implements Serializable {//部门编…

学生上课睡觉班主任怎么处理_【师问师答】学生上课说话,点名批评还嘴怎么办?...

案例我是一个初二的英语老师&#xff0c;昨天上课一男生一直在说话。我点了他名字之后毫不畏惧&#xff0c;仍然接着说话。后来我让他站起来&#xff0c;他说他腰痛不能站。又继续和同桌说话&#xff0c;我火大啊&#xff0c;让他站出去说完了再进来。他就在座位上嘀嘀咕咕&…

.NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类

0x00 为什么要引入扩展方法 有的中间件功能比较简单&#xff0c;有的则比较复杂&#xff0c;并且依赖其它组件。除了直接用ApplicationBuilder的Use()方法注册中间件外&#xff0c;还可以使用ApplicationBuilder的扩展方法UseMiddleware()注册中间件。这种情况下可以注册类型&a…

Spring Boot进阶之Web进阶 代码推送的github上面去

还是搜狗的输入法比较好 Exception.class 上面开不见的部分是这里的 代码上次github上面去保存起来 https://github.com/yangjiabinylg/girl2 https://github.com/yangjiabinylg/girl2 全部做完了 代码提交到github 上面去了

JVM初探- 使用堆外内存减少Full GC

转载自 JVM初探- 使用堆外内存减少Full GC问题: 大部分主流互联网企业线上Server JVM选用了CMS收集器(如Taobao、LinkedIn、Vdian), 虽然CMS可与用户线程并发GC以降低STW时间, 但它也并非十分完美, 尤其是当出现Concurrent Mode Failure由并行GC转入串行时, 将导致非常长时间的…

快捷生成---QQ点击联系我的方法

第一步 第二步 第三步 把uin2764954910 p2:2764954910:53 换成自己的QQ号 运行 完结撒花

.NET Core中间件的注册和管道的构建(1)---- 注册和构建原理

0x00 问题的产生 管道是.NET Core中非常关键的一个概念&#xff0c;很多重要的组件都以中间件的形式存在&#xff0c;包括权限管理、会话管理、路由等。所以搞明白中间件是如何注册并最终构建成管道的很重要。园子里很多先驱早已经开始了这方面的研究学习&#xff0c;也写了很多…