隨筆-17  評(píng)論-6  文章-1  trackbacks-0
          在c++中new的對(duì)象,如果不返回java,必須用release掉,否則內(nèi)存泄露。包括NewStringUTF,NewObject
          。如果返回java不必release,java會(huì)自己回收。

           jstring jstr = env->NewStringUTF((*p).sess_id);
             ...
           env->DeleteLocalRef( jstr);

          jobject jobj = env->NewObject(clazz,midInit);
          return jobj;

          內(nèi)存泄露可以先從windows資源管理器中,看到隨程序運(yùn)行,內(nèi)存不斷增長(zhǎng)的趨勢(shì),具體可以用hp jmeter檢測(cè)在運(yùn)行程序時(shí),加jvm參數(shù) -Xrunhprof:heap=all,cutoff=0 ,生成java.hprof.txt,用jmeter打開(kāi),Metric -> Residual Objects (Count),可以看到未回收的對(duì)象,選中要查看的對(duì)象,點(diǎn)Mark記錄下要查看的對(duì)象,Window -> New Window 打開(kāi)新窗口,用Metric -> Reference Graph Tree,然后點(diǎn)Find Immediately可以看到對(duì)象被哪里引用。


          找出內(nèi)存泄漏另一方法

          程序有內(nèi)存泄漏的第一個(gè)跡象通常是它拋出一個(gè) OutOfMemoryError,或者因?yàn)轭l繁的垃圾收集而表現(xiàn)出糟糕的性能。幸運(yùn)的是,垃圾收集可以提供能夠用來(lái)診斷內(nèi)存泄漏的大量信息。如果以 -verbose:gc 或者 -Xloggc 選項(xiàng)調(diào)用 JVM,那么每次 GC 運(yùn)行時(shí)在控制臺(tái)上或者日志文件中會(huì)打印出一個(gè)診斷信息,包括它所花費(fèi)的時(shí)間、當(dāng)前堆使用情況以及恢復(fù)了多少內(nèi)存。記錄 GC 使用情況并不具有干擾性,因此如果需要分析內(nèi)存問(wèn)題或者調(diào)優(yōu)垃圾收集器,在生產(chǎn)環(huán)境中默認(rèn)啟用 GC 日志是值得的。

          有工具可以利用 GC 日志輸出并以圖形方式將它顯示出來(lái),JTune 就是這樣的一種工具(請(qǐng)參閱 參考資料)。觀察 GC 之后堆大小的圖,可以看到程序內(nèi)存使用的趨勢(shì)。對(duì)于大多數(shù)程序來(lái)說(shuō),可以將內(nèi)存使用分為兩部分:baseline 使用和 current load 使用。對(duì)于服務(wù)器應(yīng)用程序,baseline 使用就是應(yīng)用程序在沒(méi)有任何負(fù)荷、但是已經(jīng)準(zhǔn)備好接受請(qǐng)求時(shí)的內(nèi)存使用,current load 使用是在處理請(qǐng)求過(guò)程中使用的、但是在請(qǐng)求處理完成后會(huì)釋放的內(nèi)存。只要負(fù)荷大體上是恒定的,應(yīng)用程序通常會(huì)很快達(dá)到一個(gè)穩(wěn)定的內(nèi)存使用水平。如果在應(yīng)用程序已經(jīng)完成了其初始化并且負(fù)荷沒(méi)有增加的情況下,內(nèi)存使用持續(xù)增加,那么程序就可能在處理前面的請(qǐng)求時(shí)保留了生成的對(duì)象。


          圖 1 顯示  GC 之后應(yīng)用程序堆大小隨著時(shí)間的變化圖。上升趨勢(shì)是存在內(nèi)存泄漏的警示信號(hào)。(在真實(shí)的應(yīng)用程序中,坡度不會(huì)這么大,但是在收集了足夠長(zhǎng)時(shí)間的 GC 數(shù)據(jù)后,上升趨勢(shì)通常會(huì)表現(xiàn)得很明顯。)


          圖 1. 持續(xù)上升的內(nèi)存使用趨勢(shì)

          確信有了內(nèi)存泄漏后,下一步就是找出哪種對(duì)象造成了這個(gè)問(wèn)題。所有內(nèi)存分析器都可以生成按照對(duì)象類(lèi)進(jìn)行分解的堆快照。有一些很好的商業(yè)堆分析工具,但是找出內(nèi)存泄漏不一定要花錢(qián)買(mǎi)這些工具 —— 內(nèi)置的 hprof 工具也可完成這項(xiàng)工作。要使用 hprof 并讓它跟蹤內(nèi)存使用,需要以 -Xrunhprof:heap=sites 選項(xiàng)調(diào)用 JVM。

          清單 3 顯示分解了應(yīng)用程序內(nèi)存使用的 hprof 輸出的相關(guān)部分。(hprof 工具在應(yīng)用程序退出時(shí),或者用 kill -3 或在 Windows 中按 Ctrl+Break 時(shí)生成使用分解。)注意兩次快照相比,Map.EntryTaskint[] 對(duì)象有了顯著增加。

          請(qǐng)參閱 清單 3

          清單 4 展示了 hprof 輸出的另一部分,給出了 Map.Entry 對(duì)象的分配點(diǎn)的調(diào)用堆棧信息。這個(gè)輸出告訴我們哪些調(diào)用鏈生成了 Map.Entry 對(duì)象,并帶有一些程序分析,找出內(nèi)存泄漏來(lái)源一般來(lái)說(shuō)是相當(dāng)容易的。


          清單 4. HPROF 輸出,顯示 Map.Entry 對(duì)象的分配點(diǎn)
          
          
          TRACE 300446:
          	java.util.HashMap$Entry.<init>(<Unknown Source>:Unknown line)
          	java.util.HashMap.addEntry(<Unknown Source>:Unknown line)
          	java.util.HashMap.put(<Unknown Source>:Unknown line)
          	java.util.Collections$SynchronizedMap.put(<Unknown Source>:Unknown line)
          	com.quiotix.dummy.MapLeaker.newTask(MapLeaker.java:48)
          	com.quiotix.dummy.MapLeaker.main(MapLeaker.java:64)
          




          另外
          jstring jstr = (jstring)env->CallObjectMethod(authenRequest, mid_authenReq_getSdId_S);
           env->GetStringUTFRegion(jstr,0,env->GetStringLength(jstr),authenReq.sd_id);
          當(dāng)jstr是null時(shí),env->GetStringLength(jstr)會(huì)出錯(cuò),導(dǎo)致jvm崩潰
          posted on 2006-03-02 11:23 小鐵匠 閱讀(4243) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): java
          主站蜘蛛池模板: 北安市| 白玉县| 垫江县| 长治县| 华安县| 阜阳市| 资源县| 黄梅县| 胶州市| 北辰区| 甘德县| 宜都市| 阳新县| 梨树县| 吐鲁番市| 平山县| 临西县| 夹江县| 乡宁县| 兴安县| 疏附县| 苏尼特左旗| 和龙市| 聂荣县| 伊宁市| 肇源县| 遂昌县| 霞浦县| 卢氏县| 五莲县| 无棣县| 阿拉善盟| 朝阳县| 安泽县| 新巴尔虎左旗| 大埔县| 泰兴市| 西乌珠穆沁旗| 方山县| 永胜县| 沁阳市|