JAVA性能分析工具--Jvisualvm使用方法

2023-11-18

JDK自带的JAVA性能分析工具。它已经在你的JDK bin目录里了,只要你使用的是JDK1.6 Update7之后的版本。点击一下jvisualvm.exe图标它就可以运行了。

这里是VisualVM 的官方网站:https://visualvm.dev.java.net,资料很全,同时提供VisualVM最近版本下载。

1.安装

只要安装JDK即可,运行jvisualvm.exe ,选择【工具】——【插件】——【可用插件】

·

2使用

2.1.远程机器设置

要从远程应用程序中检索数据,需要在远程 JVM 上运行 jstatd 实用程序。即要进行以下操作:

1)在jdk 安装目录的bin目录下新建文件jstatd.all.policy,文件内容为:  

grant codebase "file:${java.home}/../lib/tools.jar" {

permission java.security.AllPermission;

};

2)再新建文件jstatd.sh ,文件内容为:

./jstatd -J-Djava.security.policy=jstatd.all.policy

3)启动jstat : nohup jstatd.sh & (默认启动端口为1099)

4)配置resin.conf,把以下注释打开:

   <!-- no use args

     <jvm-arg>-Xdebug</jvm-arg>

     <jvm-arg>-Dcom.sun.management.jmxremote</jvm-arg>

2.2.添加远程监控机器

2.3.配置Jconsole

1)在应用的resin配置文件中加配置:

<jvm-arg>-Dcom.sun.management.jmxremote</jvm-arg>

<jvm-arg>-Dcom.sun.management.jmxremote.port=9009</jvm-arg>

<jvm-arg>-Dcom.sun.management.jmxremote.ssl=false</jvm-arg>

<jvm-arg>-Dcom.sun.management.jmxremote.authenticate=false</jvm-arg>

2)选择Tools菜单里的Plugins菜单,点击 'VisualVM-JConsole' 然后点击'Install' 按钮

3)安装完毕后重新启动VisualVm

4)配置JConsole页签,点击'JConsole Plugins'按钮

5)点击'Add JAR/Folder'按钮,

6)添加JDK_HOME/demo/management/JTop/JTop.jar

7)重新打开监控页面,可以看到JConsole正常工作

2.4.远程监控cpu使用情况

点采样器栏:

点击cpu,观察到cpu使用状况,点击snapshot,采取结果,可以选择查看方法、类或包的cpu使用情况,使用工具可以查找想要查看的方法、类或包:

2.5.GC监控

1)选择要监控的pid,查看GC情况

如果Old区满了,每次回收都很少或者回收不了,说明GC有问题。

2.6.远程监控内存泄露、解决内存溢出问题

1)内存泄露、溢出的异同

同:都会导致应用程序运行出现问题,性能下降或挂起。

异:

v内存泄露是导致内存溢出的原因之一;内存泄露积累起来将导致内存溢出。

v内存泄露可以通过完善代码来避免;内存溢出可以通过调整配置来减少发生频率,但无法彻底避免。

2)监测内存泄漏

·内存泄漏是指程序中间动态分配了内存,但在程序结束时没有释放这部分内存,从而造成那部分内存不可用的情况,重启计算机可以解决,但也有可能再次发生内存泄露,内存泄露和硬件没有关系,它是由软件设计缺陷引起的。  

·内存泄漏可以分为4类:

a. 常发性内存泄漏。发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。

b.偶发性内存泄漏。发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。所以测试环境和测试方法对检测内存泄漏至关重要。

c.一次性内存泄漏。发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块仅且一块内存发生泄漏。比如,在类的构造函数中分配内存,在析构函数中却没有释放该内存,所以内存泄漏只会发生一次。

d.隐式内存泄漏。程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。所以,我们称这类内存泄漏为隐式内存泄漏。

3)Heap dump 分析

每隔一段时间给所检测的java应用做一次heap dump:

(或者在响应应用pid上鼠标右键heap dump)弹出以下提示框:

在应用服务器将此文件下载到jvisual vm所在的机器上,file--load打开此文件,如下面三图所示:

 

对比上面三个截图,发现似乎有个东西在急速飙升,仔细一看是这个对象:org.eclipse.swt.graphics.Image 在第一章图中这个还没排的上,第二次dump已经上升到5181个,第三次就是7845个了。涨速相当快,而且和任务管理器里面看到的GDI数量增涨一致,就是它了。

问题到这儿就比较清楚了,回到代码里面仔细一看可以发现,是某个地方反复的用图片来创建Image对象导致的,改掉以后搞定问题。

到这里其实我想说的是,Java使用起来其实要比C++更容易导致内存泄漏。对于C++来说,每一个申请的对象都必须明确释放,任何没有释放的对象都会导致memleak,这是不可饶恕的,而且这类问题已经有很多工具和方法来解决。但是到了Java里面情况就不同了,对于Java程序员来说对象都是不需要也无法主动销毁的,所以一般的思路是:随用随new,用完即丢。很多对象具体的生命周期可能连写代码的人自己也不清楚,或者不需要清楚,只知道某个时刻垃圾收集器会去做的,不用管。但很可能某个对象在“用完即丢”的时候在另一个不容易发现的地方被保存了一个引用,那么这个对象就永远不会被回收。更加糟糕的是整个程序从设计之初就没有考虑过对象回收的问题,对于C++程序员来说memleak必然是一个设计错误,但是对Java程序员来说这只是一个疏忽,而且似乎没有什么好的办法来避免。今天看到的这个问题是因为GDI泄漏会造成严重后果才被重视,但如果仅仅是造成内存泄漏,那这个程序可能得连续跑上个十天半个月才会发现问题。最后就是,对于c++,错误的代码在测试阶段就可以快速的侦测出哪怕一个byte的memleak并加以改正,但是对于java程序,理论上没有哪个工具能够知道是不是有泄漏,因为除了作者自己以外没有人能够知道一个被引用的对象是不是应该被销毁,只有通过大量的,长期的压力测试才能发现问题,这是很危险的一件事情。

4)解决内存溢出问题

1、java.lang.OutOfMemoryError: PermGen space

JVM管理两种类型的内存,堆和非堆。堆是在JVM启动时创建;非堆是留给JVM自己用的,用来存放类的信息的。它和堆不同,运行期内GC不会释放空间。如果web app用了大量的第三方jar或者应用有太多的class文件而恰好MaxPermSize设置较小,超出了也会导致这块内存的占用过多造成溢出,或者tomcat热部署时侯不会清理前面加载的环境,只会将context更改为新部署的,非堆存的内容就会越来越多。

PermGen space的全称是Permanent Generation space,是指内存的永久保存区域,这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中,它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的应用中有很CLASS的话,就很可能出现PermGen space错误,这种错误常见在web服务器对JSP进行pre compile的时候。如果你的WEB APP下都用了大量的第三方jar, 其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。

如上图所示,PermGen在程序运行一段时间后超出了我们指定的128MB,通过Classes视图看到,Java在运行的同时加载了大量的类到内存中。PermGen会存储Jar或者Class的描述信息;所以在class大量增加的同时PermGen超出了我们指定的范围。为了让应用稳定,我们需要探寻新的PermGen范围。检测时段时候后(如下图)发现PermGen在145MB左右稳定,那么我们就得到了稳定的新参数;这样PermGen内存溢出的问题得到解决。

2、java.lang.OutOfMemoryError: Java heap space

第一种情况是个补充,主要存在问题就是出现在这个情况中。其默认空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。如果内存剩余不到40%,JVM就会增大堆到Xmx设置的值,内存剩余超过70%,JVM就会减小堆到Xms设置的值。所以服务器的Xmx和Xms设置一般应该设置相同避免每次GC后都要调整虚拟机堆的大小。假设物理内存无限大,那么JVM内存的最大值跟操作系统有关,一般32位机是1.5g到3g之间,而64位的就不会有限制了。

注意:如果Xms超过了Xmx值,或者堆最大值和非堆最大值的总和超过了物理内存或者操作系统的最大限制都会引起服务器启动不起来。

垃圾回收GC的角色,JVM调用GC的频度还是很高的,主要两种情况下进行垃圾回收:

一个是当应用程序线程空闲;另一个是java内存堆不足时,会不断调用GC,若连续回收都解决不了内存堆不足的问题时,就会报out of memory错误。因为这个异常根据系统运行环境决定,所以无法预期它何时出现。

根据GC的机制,程序的运行会引起系统运行环境的变化,增加GC的触发机会。

为了避免这些问题,程序的设计和编写就应避免垃圾对象的内存占用和GC的开销。显示调用System.GC()只能建议JVM需要在内存中对垃圾对象进行回收,但不是必须马上回收。一个是并不能解决内存资源耗空的局面,另外也会增加GC的消耗。

2.7.如何避免内存泄漏、溢出

1)尽早释放无用对象的引用。

好的办法是使用临时变量的时候,让引用变量在退出活动域后自动设置为null,暗示垃圾收集器来收集该对象,防止发生内存泄露。

2) 程序进行字符串处理时,尽量避免使用String,而应使用StringBuffer。

因为每一个String对象都会独立占用内存一块区域,如:

1.String str = "aaa";    

2.String str2 = "bbb";    

3.String str3 = str + str2;    

4.// 假如执行此次之后str , str2再不被调用,那么它们就会在内存中等待GC回收;    

5.// 假如程序中存在过多的类似情况就会出现内存错误;  

3) 尽量少用静态变量。

因为静态变量是全局的,GC不会回收。

4) 避免集中创建对象尤其是大对象,如果可以的话尽量使用流操作。

JVM会突然需要大量内存,这时会触发GC优化系统内存环境; 一个案例如下:

1.// 使用jspsmartUpload作文件上传,运行过程中经常出现java.outofMemoryError的错误,    

2.// 检查之后发现问题:组件里的代码    

3.m_totalBytes = m_request.getContentLength();    

4.m_binArray = new byte[m_totalBytes];    

5.// totalBytes这个变量得到的数极大,导致该数组分配了很多内存空间,而且该数组不能及时释放。    

6.// 解决办法只能换一种更合适的办法,至少是不会引发outofMemoryError的方式解决。    

7.// 参考:http://bbs.xml.org.cn/blog/more.asp?name=hongrui&id=3747  

5) 尽量运用对象池技术以提高系统性能。

生命周期长的对象拥有生命周期短的对象时容易引发内存泄漏,例如大集合对象拥有大数据量的业务对象的时候,可以考虑分块进行处理,然后解决一块释放一块的策略。

6) 不要在经常调用的方法中创建对象,尤其是忌讳在循环中创建对象。

可以适当的使用hashtable,vector 创建一组对象容器,然后从容器中去取那些对象,而不用每次new之后又丢弃。

7) 优化配置。

a.设置-Xms、-Xmx相等;

b.设置NewSize、MaxNewSize相等;

c.设置Heap size, PermGen space:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JAVA性能分析工具--Jvisualvm使用方法 的相关文章

随机推荐

  • loadrunner负载生成器;

    负载生成器 Load Generators 是脚本生成的负载引擎 相当于加压机 主要功能是生成虚拟用户进行负载 在默认的情况下使用本地的负载生成器来运行脚本 但是每生成一个虚拟用户 需要话费负载生成器大约2M 3M的内存空间 通常运行CON
  • java8有哪些jvm参数

    Java8中的JVM参数有很多种 这里列出一些常用的 server 指定JVM运行在服务器模式 在服务器环境下性能会更好 Xmx 设置JVM最大可用内存 Xms 设置JVM初始内存 XX PermSize 设置持久代 Perm Gen 的初
  • Python常用库大全

    作者 史豹 链接 https www zhihu com question 20501628 answer 223340838 来源 知乎 著作权归作者所有 商业转载请联系作者获得授权 非商业转载请注明出处 环境管理 管理 Python 版
  • Visual Studio 2017 远程调试器(MSVSMON.EXE) 找不到连接

    Visual Studio 2017 远程调试器 MSVSMON EXE 找不到连接 用的是wifi上网 而远程主机是有线连接 经过几个小时的排查 终于发现不在一个网段内 把wifi改成有线 确保和远程主机在一个网段内 就可以联上了
  • 【node】12、Koa实现简单爬虫案例

    效果图如下 首先我们新建文件夹 进入终端 初始化node项目 npm init y 安装koa搭建服务模块 npm install koa 安装superagent发送请求模块 npm install superagent 安装cheeri
  • 有关Proteus安装时的一些报错

    在安装Proteus的之后 使用的时候经常会出现 已使用符号sMKRORIGIN但未在库中找到 或者许多找不到文件在哪里的一些许多错误 我也是经常遇到 然后也是一点一点找资料解决 有时候这种方法能够解决 有时候又不能解决 确实很让人头疼 所
  • java: MySQL Metadata

    https www baeldung com jdbc database metadata https docs oracle com en java javase 11 docs api java sql java sql Databas
  • ant design pro v5 配置拦截器,header

    ant design pro v5 配置拦截器 header 1 资料文档 https umijs org zh CN plugins plugin request requestinterceptors 2 编写app tsx 我这里是自
  • 创建一个空的Git仓库,然后本地代码推上去

    这篇文章说的是如何将本地代码库推送到远端空的代码仓库 如需了解如何从远端代码仓库克隆代码到本地 看这里 1 创建代码仓库 2 终端进入本地代码库文件夹内 3 将本地和远端联系起来 并给远端起个名字 git remote add myOwnC
  • Hudi和Kudu的比较

    与Kudu相比 Kudu是一个支持OLTP workload的数据存储系统 而Hudi的设计目标是基于Hadoop兼容的文件系统 如HDFS S3等 重度依赖Spark的数据处理能力来实现增量处理和丰富的查询能力 Hudi支持Increme
  • 微信小程序WE分析----事件分析

    目录 web分析 小程序 事件分析概述 1 新增事件管理 事件参数说明 1 填写事件配置 2 小程序添加上报代码 将上报代码添加到小程序中 3 测试事件数据上报 测试事件上报的数据是否正确 属性管理 字典管理 新增事件分析 创建事件分析 添
  • Web自动化之Selenium常用操作

    本文总结使用selenium进行web UI自动化时 会用到的一些常用操作 定位元素 driver find element by xpath 1 绝对路径 2 元素属性 3 层级和属性结合 4 使用逻辑运算符 driver find el
  • 磁盘类型和相关术语学习笔记

    磁盘类型和相关术语 在 Linux 中一切皆文件 但是类型不同 例如使用 ls l 对于设备文件和普通文件有一部分内容是不同的 即普通文件有大小 而设备文件有主设备号和次设备号 没有大小 ll 1 txt dev sda dev sda1
  • TCP/IP、UDP协议

    TCP IP协议是Internet最基本的协议 Internet国际互联网络的基础 由网络层的IP协议和传输层的TCP协议组成 通俗而言 TCP负责发现传输的问题 一有问题就发出信号 要求重新传输 直到所有数据安全正确地传输到目的地 而IP
  • module ‘keras.api._v1.keras.datasets.mnist‘ has no attribute ‘train‘AttributeError: module ‘numpy‘ h

    AttributeError module numpy has no attribute no nep50 warning 尝试过更新numpy但是更新不了 module keras api v1 keras datasets mnist
  • 常见 Web 中间件及其漏洞概述(一):IIS

    目录 PUT漏洞 漏洞原理 复现 修复 短文件名猜解 漏洞原理 IIS短文件名产生 复现 短文件漏洞的局限性 IIS短文件名扫描工具 修复 远程代码执行 解析漏洞 IIS 6 0 基于文件名 基于目录名 IIS 7 0 7 5 IIS PH
  • docker容器内访问宿主机127.0.0.1服务

    docker容器内访问宿主机127 0 0 1服务 原创 技术生活 技术生活 2020 04 15 09 00 点击上方 技术生活 选择 设为星标 做积极的人 而不是积极废人 背景 原因分析 解决方案 背景 已经通过docker启动的ela
  • mac m1 搭建 arduino 环境

    前前后后弄了几次 arduino 环境 这次就以 mac m1 为例 来做一个笔记 搭建 arduino 首先 第一步肯定是安装 arduino 这直接去官网下载安装就好了 地址放在下面 https www arduino cc en so
  • Android 打包aar给unity3d使用 项目心得

    步骤 制作androidproject 修改build gradle配置 打包aar 1 混淆打包aar 2 jar包导出 3 在其他的android工程引入aar 导入unity项目 运行unity3d输出apk包 新建一个project
  • JAVA性能分析工具--Jvisualvm使用方法

    JDK自带的JAVA性能分析工具 它已经在你的JDK bin目录里了 只要你使用的是JDK1 6 Update7之后的版本 点击一下jvisualvm exe图标它就可以运行了 这里是VisualVM 的官方网站 https visualv