SFFamily 板


LINE

※ [本文轉錄自 java 看板] 作者: willieliao (Willie Liao) 看板: java 標題: Re: [問題] 請教在linux跑的java錯誤訊息 時間: Thu Dec 27 13:53:23 2007 ※ 引述《willieliao (Willie Liao)》之銘言: : 你的程式有memory leak,也就是說程式跑越久memory就越用越多, : 而且garbage collection之後也不會下降,最後就是出現outofmemory exception : 這種情況短期治標是加大memory(-Xmx多少m),長期治本當然是要看哪裡有memory : leak,也就是物件越漲越大,reference的物件越來越多,而沒有從memory中releas : e掉。雖然java 有garbage collection,但是有reference到的物件是不會被collect的 .... : 推 dwi2:推一下這篇!我之前也有遇過這種問題 11/24 20:18 : 推 slalala:不知道可否請您分享 讓新手注意如何建少記體用量的技巧呢? 11/24 22:53 : → slalala:因為我寫的批次處理的程式 都還是會使記憶體用量偏大 11/24 22:55 : → slalala:除非縮視窗才會釋放些空間應該有些地方觀念上寫的不夠嚴謹 11/24 22:56 不好意思回一下有點久的文章,因為我現在才看到有人推文問問題。一般沒有寫過 c++直接寫java的新手因為沒有destroy object的觀念,特別容易造成memory leak 首先我要強力推薦使用profiler,我們公司是用要付費的borland,不過免費的 jconsole(附在jdk1.5以上,到jdk_home/bin找jconsole.exe)更好用,而且有 強大的find thread deadlock功能(大感謝!讓我少死很多腦細胞)。 如果你找不出來哪裡有memory leak的話,讓程式run一段時間用profiler去監視 哪種class的instance數量一直上升不下降,那就有可能是來源。 回到程式本身,一些小技巧如下: 第一,絕對不要寫出無限迴圈!即使是有限迴圈,也要盡量減少跑的次數。 public int getThis() { return this.getThis(); } 以上的程式編譯會過,但是一跑保證不到一秒就會出現stackoverflowerror。 第二,盡量不要保留intermediate(過渡)的物件 最耗記憶體的寫法: public void writeXML(FileWriter writer) { Vector tempV = new Vector(); tempV.add("<root>"); for (int i = 0; i < 10000; i++) { tempV.add("<value> + String.valueOf(i) + "</value>"); } tempV.add("</root>"); for (int j = 0; j < tempV.size(), j++) { writer.write(tempV.get(j)); //這裡不需要cast } writer.close(); } 這個call會暫存10002個string objects.. 有點sense的寫法: public void writeXML(FileWriter writer) { StringBuffer sb = new StringBuffer(); sb.append("<root>"); for (int i = 0; i < 10000; i++) { sb.append("<value>" + String.valueOf(i) + "</value>"); } sb.append("</root>"); writer.write(sb.toString()); writer.close(); } 這個寫法只會有一個stringbuffer的instance,但是這個instance會很大。 最省記憶體的寫法 public void writeXML(FileWriter writer) { writer.write("<root>"); for (int i = 0; i < 10000; i++) { writer.write("<value>" + String.valueOf(i) + "</value>"); } writer.write("</root>"); writer.close(); } 一邊生成一邊寫出最省記憶體.. 第三,不需要的物件要清掉,也就是把本來指向這個物件的variable 指向null private HashMap tempHashMap = new HashMap(); public void doSomething() { for (int i = 0; i < 100000; i++) { tempHashMap.put(new Object(), new Object()); } ... } 這個doSomething()假設你call他1000次,程式還是會執行無誤。但是,你的 tempHashMap就會長大成1000倍,不但變慢還會memory leak。 解決之道要嗎把變數搬進method裡,要嗎像這樣: public void doSomething() { for (int i = 0; i < 100000; i++) { tempHashMap.put(new Object(), new Object()); } ... tempHashMap.clear(); } 或是 private HashMap tempHashMap; public void doSomething() { tempHashMap = new HashMap(); for (int i = 0; i < 100000; i++) { tempHashMap.put(new Object(), new Object()); } ... tempHashMap = null; } 這兩種方法的的效果其實差不多,不過後者更省記憶體一點。壞處是有的時候不小心 null pointer就會跑出來。 最後,盡量避免一些java中memory intensive的api calls。 這個的話真的要靠經驗。比方說,java的regular expression和 JAXP(java API for xml)裡面都有很多吃memory的怪獸(美國這邊我們叫它memory hog)。碰到的 話也只好用profiler找出來在想辦法避開了。 大概就想到這麼多吧,板上的神人大大門不要客氣盡量鞭... Willie --



※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 76.111.69.123
1F:→ willieliao:好像錯字很多,各位大大多包含,中文越來越不行了 12/27 14:07
2F:推 PsMonkey:第二點看不太懂.... 12/27 15:01
3F:→ willieliao:改一下好了,其實2跟三差不多 12/27 15:20
4F:→ willieliao:我改一下例子,請大家暫時不要推文 12/27 15:43
※ 編輯: willieliao 來自: 76.111.69.123 (12/27 16:07)
5F:→ willieliao:改好了,版大看看有沒有比較通順點 12/27 16:08
6F:推 kojilin:第一個應該是噴StackOverflowError之類的? 12/27 16:17
7F:→ willieliao:nice catch, 我改一下。 12/27 16:43
※ 編輯: willieliao 來自: 76.111.69.123 (12/27 16:46)
8F:→ willieliao:第一點其實應該要解釋一下outofMemorryError (HEAP) 12/27 17:01
9F:→ willieliao:跟stackoverflowerror(STACK)的區別,不過太晚了明天 12/27 17:02
10F:→ willieliao:在來改好了 12/27 17:03
11F:推 PsMonkey:ㄜ... 還有,第三點的例子... 個人覺得不是很恰當 XD 12/27 18:47
12F:推 qrtt1:第三個例子是很多短命鬼 12/27 21:04
13F:推 linshihpong:有教學總比看到教學再抓錯好...推一個~ 12/27 21:10
14F:→ willieliao:恩 舉第三點的例子是因為我下面的junior programmer 12/27 23:13
15F:→ willieliao:常常cache用完不清掉...我再來想想有沒有更好的例子 12/27 23:14
-- 三月的柳絮不飛 妳的心如小小的寂寞的城 我達達的馬蹄是美麗的錯誤 我不是歸人 我是馬~ --



※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.132.117.169







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:e-shopping站內搜尋

TOP