中文JAVA技術平等自由協作創造

          Java專題文章博客和開源

          常用鏈接

          統計

          最新評論

          源碼實現實時獲取Java堆內存信息

            如果大家有遇到過Java內存泄露問題,而且親自動手去定位和分析經歷的同學來講,獲取Java的堆內信息對了內存使用情況的問題分析和定位是非常有幫助了。例如我們常用的MAT工具,可以較方便的讓我們定位程序中內存的使用情況,是哪塊導致了內存的泄露等。

            但由于傳統的分析過程比較麻煩,需要使用Jdk的jmap(Java Memory Map)命令把heap內存dump到一個文件,然后用MAT進行分析。所以本文介紹一種方法可以實現在線查看heap內存的使用情況,并附上源碼實現,希望對大家有幫助。由于目前調研中只找到了Sun JDK6以及以上版本的實現,所以目前該方案只支持Sun JDK6或以上。如果其他同學有其它版本的JDK實現分享,歡迎一起交流。

            整體實現思路如下:

            1.       JDK6中在tools.jar類庫里有一個com.sun.tools.attach.VirtualMachine類,該類可以獲得JVM虛擬機的相關控制權限證券從業代考 期貨從業代考

            2.       利用getPids.exe或其它工具獲取需要監控的JVM 的pid進程號信息

            3.       利用反射調用VirtualMachine的attach方法,獲取VirtualMachine的實例對象

            4.       復用反射調用VirtualMachine實例的heapHisto方法,參數為 –all, 可獲到JVM的堆內存信息

            5.       最后解析heapHisto方法返回的輸入流,讀取內存數據即可獲得當前JVM的堆內存數據會計從業代考 注冊會計師代考

            下面帖出的主要代碼來說明各步驟具體實現方法:

            l JDK6中在tools.jar類庫里有一個com.sun.tools.attach.VirtualMachine類,該類可以獲得JVM虛擬機的相關控制權限。

            private static Class<?> findVirtualMachineClass() throws ClassNotFoundException,

            MalformedURLException {

            // JVM 虛擬機操作類

            final String virtualMachineClassName = "com.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

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

            1:         14948        1892768 [C

            2:           958         567568 [B

            3:          1870         215584 <symbolKlass>

            4:          7366         176784 java.lang.String

            5:           132          88104 [I

            6:           841          86360 <constMethodKlass>

            7:           841          67672 <methodKlass>

            8:           968          61152 [Ljava.lang.Object;

            9:           101          48152 <constantPoolKlass>

            10:          2593          41488 java.lang.StringBuilder

            11:           101          40600 <instanceKlassKlass>

            12:           952          30464 java.util.TreeMap$Entry

            13:            79          25112 <constantPoolCacheKlass>

            14:           310          22280 [S

            15:           746          17904 sun.jvmstat.perfdata.monitor.AliasFileParser$Token

            16:           367          17616 java.nio.HeapCharBuffer

            Total         39840        3645336

            null

            因為內容太長,只截取了部分

            因為讀取的是文本內容,而且格式是完全固定的,所以大家可以直接解析里面的內容。主要是后面三例,一個是實現的個數,一個是實際的數據內容,最后一個是實例關聯的類名稱。

          posted on 2013-03-12 20:32 好不容易 閱讀(213) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          PK10開獎 PK10開獎
          主站蜘蛛池模板: 莱阳市| 景泰县| 永仁县| 锡林浩特市| 伊宁市| 乳山市| 营山县| 林口县| 璧山县| 秦安县| 崇文区| 台湾省| 稷山县| 平阳县| 兴化市| 任丘市| 鄂托克前旗| 南丰县| 繁峙县| 阿拉尔市| 志丹县| 尼玛县| 岳西县| 滦平县| 合川市| 孙吴县| 桓仁| 临武县| 新化县| 玉田县| 溆浦县| 焉耆| 长兴县| 班玛县| 四子王旗| 英山县| 贡嘎县| 神木县| 麻阳| 永昌县| 武威市|