这种情况,如何设置JVM参数?难,头疼,高分

dddeee 2007-03-29 08:39:32
我最近做的一个项目,在性能上有严重的问题,希望大家给些建议。

情况如下:

一个java程序,需要不断地从服务器上接收信息(一些二进制数据),并且把它们缓存在内存中。(一个hashmap来放它们)
每个二进制数据的大小大约0.5K,每秒约80个。
这些二进制数据被解析后,每一个都会生成一个对象,但每个对象内部都有一些更小的对象的引用,来表示信息内容,平均下来每个信息大约有20个这样的小对象。在生成对象的过程中,有大量的短命对象生成。
一天下来,大约会收到500000个这样的信息。

合计起来,每天大约有250M左右的内存被固定占用。
有500000个这样的信息对象和500000*20个小对象被一直引用。

我使用默认运行方式(使用JVM默认参数),很快就CPU100%,程序运行很慢,不一会儿就outofmemory。
后来改成了-verbose:gc -Xms60M -Xmx512M,发现在接收前5000个信息时很快,只有少量gc。但是超过5000后,系统就非常慢,并且在不断的fullgc,经常连续好几个。

我反复检查了程序,没有发现内存泄漏,估计关键在于JVM的参数设置上,但是不会,希望大家给点意见!
...全文
1082 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
dddeee 2007-04-02
  • 打赏
  • 举报
回复
重新修改了程序,性能有了很大的改观,现在使用-server -verbose:gc -Xms60M -Xmx800M -XX:NewRatio=3 -XX:PermSize=32m -XX:MaxPermSize=300m 已经可以轻松的收取300000万条以上的信息,而且CPU的占用率也不是很高。

主要的修改是直接把收到的二进制数组以byte[]方式放入hashmap,而不是那个message对象。需要用的时候,再取出来临时构造一个message对象出来。又根据情况简化了一些函数。虽然没有以前看起来那么结构清晰,但是效率确实是提高的相当大。

谢谢各位的帮助!
王金豆 2007-03-30
  • 打赏
  • 举报
回复
应该是程序的问题吧
shjavaedu 2007-03-30
  • 打赏
  • 举报
回复
内存数据库会自己管理内存,将暂时不用的数据从内存中拿出来放在磁盘空间中,这样的话可以减少内存的使用量。
yeah920 2007-03-30
  • 打赏
  • 举报
回复
来学习了。up
lzh_lsh 2007-03-30
  • 打赏
  • 举报
回复
fresh man, 学习
捏造的信仰 2007-03-30
  • 打赏
  • 举报
回复
建议将数据持久化,也就是写到数据库或者文件当中去,以减小内存消耗。总之就是拿时间换空间。
dddeee 2007-03-30
  • 打赏
  • 举报
回复
to shjavaedu

使用内存数据库与直接用hashmap缓存,在性能上有什么区别?
shjavaedu 2007-03-30
  • 打赏
  • 举报
回复
既然你要做server,你更不能只用hashmap来做这件事情,否则多少内存可能也不够。
YuLimin 2007-03-30
  • 打赏
  • 举报
回复
用JRockit看看,另外你的JDK版本是多少?用JRMC进行监控一下,应当有效果。
ljmat427 2007-03-30
  • 打赏
  • 举报
回复
可以使用borland的内存数据库
ljmat427 2007-03-30
  • 打赏
  • 举报
回复
mark
zwgaa 2007-03-30
  • 打赏
  • 举报
回复
学习一下,第一次了解
healer_kx 2007-03-30
  • 打赏
  • 举报
回复
-Xms
dddeee 2007-03-30
  • 打赏
  • 举报
回复
忘了强调一点,这个程序又相当于一个server,对于其它机器发来的请求,要以最快的速度把缓存的信息转发过去,所以得保证它们一直在内存中(这样才快),不然我就可以使用数据库等方式保存了。

前面有朋友提到了内存数据库,不知道它是否可以解决这种问题?
自然80 2007-03-30
  • 打赏
  • 举报
回复
可以用用 SoftReference
洪泉 2007-03-29
  • 打赏
  • 举报
回复
一般来说程序都是可以优化的,应该不会占那么多内存的
shjavaedu 2007-03-29
  • 打赏
  • 举报
回复
这种事情不能靠Java程序的垃圾收集器来处理你的,象你这样的程序,你需要自己管理你的内存,将暂时不需要的内容放入硬盘中,算法可以参考操作系统同关于内存交换的算法,比如最近最久不用算法等等,当然这样的算法自己实现起来有一定难度,而且效果未必很好,毕竟有很多细节问题很难考虑周全。那么你可以考虑一下使用一个内存数据库来存储你的内容,例如hsql或者 berkly db等。

最后,添个广告,在上海想学习Java技术的人可以到 www.javaedu.com.cn 来看看。
qzjackie 2007-03-29
  • 打赏
  • 举报
回复
还是得自己来优化程序哦。
jiqi62120 2007-03-29
  • 打赏
  • 举报
回复
暂时不用的数据,写文件存硬盘阿
lixiaoxue85 2007-03-29
  • 打赏
  • 举报
回复
拆墙补漏而已,你一再的加大JVM的内存使用大小,只是延长你OUTOFMENMORY发生的时间而已
关键是看你程序,为社么会占用这么多的资源.优化程序(STRING边STRINGBUILDER?之类)或换个思路
加载更多回复(4)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧