VisualVM 使用心得

Wesley13
• 阅读 473

JDK中有个好用的工具“VisualVM”可以实时可视化的查看到java程序内存变化情况,对于理解GC和java内存管理还是有很大帮助的,以前看论坛看帖子讲到java内存管理真是各说纷纭啊!有人说“JVM的内存分为两块堆和栈”,还有人说"JVM的内存分为三块(新生代、老年代、方法区)",想必很多人和我一样都搞得有点摸不着头脑了吧。下面来眼见为实:

工欲善其事必先利其器,首先要给VisualVM安装一些插件便于我们观察jvm的内存管理情况,

1 VisualVM简单介绍

1.1 打开VisualVM(这个工具放在JDK安装目录的bin目录下,双击jvisualvm.exe即可打开),如下图所示

VisualVM 使用心得

1.2 以VisualVM自身为例,VisualVM本身也是一个java程序,当然也而已用VisualVM来分析

1.3 概述页面主要显示程序的启动参数和系统信息(如下图所示)

VisualVM 使用心得

Ø PID -- 程序启动后的进程号,在命令行中可以用 jps命令查看

Ø 主机 -- 如果是本机的话显示,localhost,如果是远程主机应该是显示远程主机的主机名或者IP

Ø 主类 -- 程序入口类(main方法所在的类)

Ø 参数 -- VisualVm 启动的时候使用的一些配置文件路径

Ø JVM -- jvm类型

Ø Java -- jdk的版本信息

Ø Java Home -- JDK安装目录

l JVM参数 -- VisualVm 启动时候设置的JVM参数

l 系统属性 -- java环境的系统参数

1.4 监视页面主要展示 系统资源占用情况(如下图所示)

VisualVM 使用心得

Ø CPU -- 展示java程序运行的时候占用的cpu资源 如下图中橙色的表示程序运行使用的cpu资源百分比,蓝色部分表示垃圾回收占用CPU资源百分比

Ø 堆 -- 这里要说明下堆内存的组成部分,堆是由老年代和新生代组成,其中新生代有由"伊甸园"和"两个幸存区组成"三部分组成,堆视图看到的资源占用实际是"老年代"、"伊甸园(Eden)"、"两个幸存者(Survivor )"的一个综合情况。

Ø PermGen --  Perm 区用来存放java类以及其他虚拟机自己的静态数据,(常被称为持久代或者方法区)

Ø 类 -- 此视图 主要展示 当前程序加载了多少个类

Ø 线程 -- 当前程序的线程启动情况

§ 执行垃圾回收 -- 手动触发一次GC 相当于在程序代码中调用(System.gc()),如果是远程连接到生产环境中请慎重点击。

§ 堆Dump -- 生产当前程序的内存快照hprof文件,对于分析内存溢出问题比较有帮助。(可以查看当前程序内存中的所有对象)

1.5 线程页面(主要展示程序中所有的线程运行状态)

Ø 线程dump – 此按钮主要生产当前程序中所有线程的快照(对分析线程死锁,比较有帮助)

Ø 时间线 – 展示每个线程的实时运行状态(不同颜色代表不同的状态)

Ø 表 – 按照二维表格的形式展示每个线程不同状态的时间统计信息

Ø 详细信息 – 用饼图展示每个线程的运行状态

VisualVM 使用心得

1.6 抽样器(应该算是线程页面功能的一个补充)

CPU-> CPU样例 – 主要展示方法消耗的CPU资源比例和时间

VisualVM 使用心得

CPU->线程CPU时间 – 主要展示线程消耗的CPU资源信息

VisualVM 使用心得

内存-> 堆柱状图 – 展示堆内存中各种对象占用的字节数和总实例数

VisualVM 使用心得

内存->PermGen – 展示方法区各种对象消耗的内存情况

VisualVM 使用心得

内存-> 每个线程分配—展示不同线程占用内存的情况

VisualVM 使用心得

1.7 增加VisualGC插件

1.7.1 点击 工具->插件,然后在插件页面进入可用插件页面,点击检查更新,如下图所示会展示所有可用插件

VisualVM 使用心得

1.7.2 选择VisualGC并点击安装,安装完成之后需要重新打开分析页面就能看到VisualGC页面,如下所示

VisualVM 使用心得

根据VisualGC中的信息可以调整程序的启动参数,这样就不会再这是启动参数的时候拍脑袋了(以前工作中设置Tomcat的启动参数的时候确实是在拍脑袋)。

按照此图中的信息来看Eden区域GC次数明显过多,可以增大此区域的内存用来减少GC次数。

对于开篇引出的话题有人说“JVM的内存分为两块堆和栈”,还有人说"JVM的内存分为三块(新生代、老年代、方法区)"该有个结论了

对于堆栈说法的人他们是根据下图中的维度来看问题的

VisualVM 使用心得

对于分代说法的人是根据下图中的维度来看待的

VisualVM 使用心得

不能说谁对谁错吧,只是看待问题的维度不同而已,这里应该明确一下它们的关系

堆 = Old+Eden+S0+S1(下图中红色圈中的范围)

栈 = PerM区 下图中蓝色圈中的范围

VisualVM 使用心得

版权声明:本文为博主原创文章,未经博主允许不得转载。

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
2年前
java 内存管理 堆和栈的理解
在JVM中,内存分为两个部分,Stack(栈)和Heap(堆),这里,我们从JVM的内存管理原理的角度来认识Stack和Heap,并通过这些原理认清Java中静态方法和静态属性的问题。一般,JVM的内存分为两部分:Stack和Heap。Heap(堆)是JVM的内存数据区。Heap的管理很复杂,每次分配不定长的内存空间,专门用来保存对象
Stella981 Stella981
2年前
JVM内存模型和类加载机制
JVM内存模型Java代码是运行在Java虚拟机(JVM)上的,Java虚拟机通过解释执行(解释器)或编译执行(编译器)来完成。Java内存模型分为5个部分:方法区(MethodArea),Java堆(Heap),Java栈(VMStack),本地方法栈(NativeMethodStack),程序计数器(PC寄存器)!(ht
Stella981 Stella981
2年前
JVM内存区域划分
JVM内存区域划分一、JVM运行时数据区划分根据《Java虚拟机规范》JVM会把它管理的内存划分为若干个不同的数据区域,如下图所示:方法区、堆、栈(虚拟机栈、本地方法栈)、程序计数器。线程私有的意思是指,JVM每遇到一个新的线程就会为他们分配栈和程序计数器。!(https
Wesley13 Wesley13
2年前
Java虚拟机堆内存(新生代)
Java中的堆是JVM所管理的最大的一块内存空间,主要用于存放各种类的实例对象。在Java中,堆被划分成两个不同的区域:新生代,老年代。新生代又被分为了三个区域:Eden,from survivor,tosurvivor。这样划分的目的是为了使JVM能够更好的管理堆内存中的对象,包括内存分配以及回收。堆的内存模型大致为:从图中可以看出:堆大
Wesley13 Wesley13
2年前
JDK8中JVM堆内存划分
一:JVM中内存JVM中内存通常划分为两个部分,分别为堆内存与栈内存,栈内存主要用运行线程方法存放本地暂时变量与线程中方法运行时候须要的引用对象地址。JVM全部的对象信息都存放在堆内存中。相比栈内存,堆内存能够所大的多,所以JVM一直通过对堆内存划分不同的功能区块实现对堆内存中对象管理。堆内存不够最常见的错误就是OOM(OutOf
Wesley13 Wesley13
2年前
Java工程师成神之路
一、基础篇1.1JVM1.1.1.Java内存模型,Java内存管理,Java堆和栈,垃圾回收http://www.jcp.org/en/jsr/detail?id133http://ifeve.com/jmmfaq/1.1.2.了解JVM各种参数及调优
Stella981 Stella981
2年前
Android 优化二 Java内存分配机制及内存泄漏
Java内存分配机制及内存泄漏目录介绍1.JVM内存管理1.1JVM内存管理图1.2Java采用GC进行内存管理。2.JVM内存分配的几种策略2.1静态的2.2栈式的2.3堆式的2.4堆和栈的区别2.5得出结论
Stella981 Stella981
2年前
JVM 面试
1、内存模型以及分区,需要详细到每个区放什么。通俗的说,Java虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。JVM主要管理两种类型内存:堆和非堆,堆内存(Heap Memory)是在Java虚拟机启动时创建,非堆内存(NonheapMemory)是在JVM堆之外的内存。简单来说,堆是Java代码可及的内
Stella981 Stella981
2年前
JVM 参数学习
一、JVM1、JVM产生GC的位置Eden(新生代)MinorGC算法(复制)Oldtenure(老年代) Major(Full)GC(整理压缩)算法2、JVM堆(Heap)内存大小参数\Xmn新生代8:1:1比例\Xms设置初始化堆内存大小 \Xmx设置堆内存最大大小 产生java.lang.
Wesley13 Wesley13
2年前
Java8内存模型
<divclass"htmledit\_views"<h1<aname"t0"</a一、JVM内存模型</h1<p</p<p<spanstyle"fontfamily:'宋体';"内存空间</span(RuntimeDataArea)中可以按照是否线程共享分为两块,线程共享的是方法区(MethodArea)和堆