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灯, 水草

请输入看板名称,例如:iOS站内搜寻

TOP