知识大全 源码实现实时获取Java堆内存信息

Posted

篇首语:事常与人违,事总在人为。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 源码实现实时获取Java堆内存信息相关的知识,希望对你有一定的参考价值。

源码实现实时获取Java堆内存信息  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  如果大家有遇到过Java内存泄露问题 而且亲自动手去定位和分析经历的同学来讲 获取Java的堆内信息对了内存使用情况的问题分析和定位是非常有帮助了 例如我们常用的MAT工具 可以较方便的让我们定位程序中内存的使用情况 是哪块导致了内存的泄露等

  但由于传统的分析过程比较麻烦 需要使用Jdk的jmap(Java Memory Map)命令把heap内存dump到一个文件 然后用MAT进行分析 所以本文介绍一种方法可以实现在线查看heap内存的使用情况 并附上源码实现 希望对大家有帮助 由于目前调研中只找到了Sun JDK 以及以上版本的实现 所以目前该方案只支持Sun JDK 或以上 如果其他同学有其它版本的JDK实现分享 欢迎一起交流

  整体实现思路如下

          JDK 中在tools jar类库里有一个 sun tools attach VirtualMachine类 该类可以获得JVM虚拟机的相关控制权限

          利用getPids exe或其它工具获取需要监控的JVM 的pid进程号信息

          利用反射调用VirtualMachine的attach方法 获取VirtualMachine的实例对象

          复用反射调用VirtualMachine实例的heapHisto方法 参数为 –all 可获到JVM的堆内存信息

          最后解析heapHisto方法返回的输入流 读取内存数据即可获得当前JVM的堆内存数据

  下面帖出的主要代码来说明各步骤具体实现方法

  l JDK 中在tools jar类库里有一个 sun tools attach VirtualMachine类 该类可以获得JVM虚拟机的相关控制权限

  private static Class<?> findVirtualMachineClass() throws ClassNotFoundException

  MalformedURLException

  // JVM 虚拟机操作类

  final String virtualMachineClassName = sun tools attach VirtualMachine ;

  try

  return Class forName(virtualMachineClassName)

   catch (final ClassNotFoundException e)

  // exception ignored try looking else where

  File file = new File(System getProperty( java home ))

  if ( jre equalsIgnoreCase(file getName()))

  file = file getParentFile()

  

  //直接从JDK的 lib目录下加载 tools jar类库

  final String[] defaultToolsLocation = lib tools jar ;

  for (final String name : defaultToolsLocation)

  file = new File(file name)

  

  final URL[] urls = file toURI() toURL() ;

  final ClassLoader cl = URLClassLoader newInstance(urls)

  //再次尝试反射查询 JVM虚拟机操作类

  return Class forName(virtualMachineClassName true cl)

  

  

  l 利用反射调用VirtualMachine的attach方法 获取VirtualMachine的实例对象

  本过程相对比较简单 获取VirtualMachine的类后 根据反射类 查询attach方法

  //获取JVM 虚拟机操作类后

  final Class<?> virtualMachineClass = findVirtualMachineClass()

  //根据反射查询 attach方法 参数为String类型

  final Method attachMethod = virtualMachineClass getMethod( attach String class)

  //通过 getpids exe工具获取当前JVM进程号

  final String pid = PID getPID()

  try

  //通过反射调用attache方法

  jvmVirtualMachine = invoke(attachMethod null pid)

   finally

  enabled = jvmVirtualMachine != null;

  

  l 复用反射调用VirtualMachine实例的heapHisto方法 参数为 –all 可获到JVM的堆内存信息

  本过程也是利用反射调用heapHisto方法 实现的代码如下

  final Class<?> virtualMachineClass = getJvmVirtualMachine() getClass()

  //反射调用 heapHisto方法 参数为 all

  final Method heapHistoMethod = virtualMachineClass getMethod( heapHisto

  Object[] class)

  //该方面返回值为InputStream

  return (InputStream) invoke(heapHistoMethod getJvmVirtualMachine()

  new Object[] new Object[] all )

  l 最后解析heapHisto方法返回的输入流 读取内存数据即可获得当前JVM的堆内存数据 通过该方法返回的一个文本内容

  Input Stream取出的结果(文本内容)示例如下

  num     #instances         #bytes class name

  

   :                 [C

   :                    [B

   :                   <symbolKlass>

   :                   java lang String

   :                     [I

   :                     <constMethodKlass>

   :                     <methodKlass>

   :                     [Ljava lang Object;

   :                     <constantPoolKlass>

   :                    java lang StringBuilder

   :                     <instanceKlassKlass>

   :                     java util TreeMap$Entry

   :                      <constantPoolCacheKlass>

   :                     [S

   :                     sun jvmstat perfdata monitor AliasFileParser$Token

   :                     java nio HeapCharBuffer

  Total                

  null

  因为内容太长 只截取了部分

cha138/Article/program/Java/hx/201311/26337

相关参考

知识大全 java资源获取分析

  在开发java程序的过程中我们经常要做的一件事就是获取资源那么什么是资源呢?说白了在计算机里那就是一堆数据只是这堆数据对我们的java程序有多种表现形式一般来说有FileURLInputStrea

知识大全 Java获取网络主机信息

Java获取网络主机信息  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  InetAddress类

知识大全 Java获取Http响应Header信息

Java获取Http响应Header信息  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  本文中演

知识大全 获取java线程中信息的两种方法[1]

   在进行多线程编程中比较重要也是比较困难的一个操作就是如何获取线程中的信息大多数人会采取比较常见的一种方法就是将线程中要返回的结果存储在一个字段中然后再提供一个获取方

知识大全 获取java线程中信息的两种方法[2]

   以上是一个多数熟悉单线程编程的人在第一反应下给出的实现方法但是该类在运行的时候输出的结果却不是期望的HelloWorld!而是Hello这是由于线程的竞争条件导致的

知识大全 获取java线程中信息的两种方法[3]

   二回调   轮询方法最大的特点是主类Main不断询问线程类是否结束这实际上大量浪费了运行时间特别是当线程特别多的时候因此如果反过来在线

知识大全 获取ServerSocket信息的方法及FTP原理

Java网络编程从入门到精通(28):获取ServerSocket信息的方法及FTP原理  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发

知识大全 java源码分析之HashMap

java源码分析之HashMap  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在Java集合类

知识大全 java源码分析之LinkedHashMap

java源码分析之LinkedHashMap  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!&nbs

知识大全 java源码分析之LinkedList

java源码分析之LinkedList  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &