浏览 4519 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (9) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-03-17
最后修改:2010-03-18
那么这位改头换面的朋友究竟是何许人也,Google了一下居然也有一大片的介绍,甚至有些Blog已经探索到JVM寻址技术。这里赞一下,很好很强大,但如同我老大所说,精确到这层面,那么我们所能做的优化工作还剩多少? Okay,看一下JDK的specification中对OutOfMemoryError 的描述: Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector. Umm, 这意思是在说由于没有更多的可用内存给GC或内存已经溢出,导致JVM无法分配新的对象,所以抛出OutOfMemoryError。我觉得这似乎在说Heap的内存溢出, 然而OutOfMemoryError完全是Stack中无法启动线程而抛出的异常。(大伙觉得java对outofmemoryerror的描述有没有问题? 看了这段简单的描述,我立马想到了JVM 的Xmx参数,难道由于Heap size 太小, 导致无法新生对象? 事实上,我的Heap Size 设置为2047M, 系统的日志记录着在OutOfMemory时, 已使用内存才300+M, 问题越来越离奇,难道是内存泄露么。为此,我通过Linux的pmap查到系统进程中,每个对象地址的使用内存大小, 以及通过jmap查看JVM的Heap 中对象的内存占用情况,都表明内存占用很正常。最后只能无功而返. 继续Google, 看到Sun的一个论坛里也有人提到: http://forums.sun.com/thread.jspa?threadID=605782&messageID=3360044 贴子里一个叫unsavory的人,他的解决方案是Threadpool, 意思是我们在生成销毁线程时,部分内存未被回收。最终导致了溢出,当然sun还有其他贴子说的更加离谱,说是在我们的项目中使用了RMI对象导致内存溢出。(摊手, 浪费了我不少时间. 事实上, 回到主题, 该异常由栈中抛出, 表明栈中无可用内存来服务线程。而JVM的内存大致可分为(这里不够严谨)内存数据区(包括Stack)+对象堆区,由于JVM实例进程寻址是一定的。所以两者此消彼涨的关系,对于32位的机子, JVM整个实例可用内存不到3G,加上我的Heap Size 设置了2G,留给数据区只有1G不到, 当时系统跑了大概500+的线程, 按照JDK1.5以来, 每个线程栈的大小为1M, 这样算出溢出就差不多了. 解决方案是减小Heap Size 的大小给数据区留下内存, 或是增加CPU位数。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-03-17
500+的线程数,是不是设计存在问题哦。
|
|
返回顶楼 | |
发表时间:2010-03-17
rain2005 写道 500+的线程数,是不是设计存在问题哦。 文件存储, Hadoop的HDFS. 500的并发读取线程, 已经很低了。 |
|
返回顶楼 | |
发表时间:2010-03-17
服务器总内存多大?如果服务器内存只有3G,给JAVA分配2G的内存的话,一样会出这个问题;
JVM启动线程消耗内存时,系统内存也同样会被消耗掉同样资源。 |
|
返回顶楼 | |
发表时间:2010-03-17
hbcui1984 写道 服务器总内存多大?如果服务器内存只有3G,给JAVA分配2G的内存的话,一样会出这个问题; JVM启动线程消耗内存时,系统内存也同样会被消耗掉同样资源。 32位机子, 4G的内存. > JVM启动线程消耗内存时,系统内存也同样会被消耗掉同样资源。 JVM启动一线程消耗1M内存, 实际上对于系统来说消耗了1 * 2 M?怎么理解, 还是只对于线程来说 ? |
|
返回顶楼 | |
发表时间:2010-03-21
* 调整java thread stack: -Xss256k 需要测试下, 基本来说是足够的. 能降低jvm内存的使用。
* 32位下, 最好不要超过1280M内存。 * 看看 ulimit -u 这个参数. 这是表示用户能拥有的线程数量。 还有OS能拥有的线程也是有限制的: thread-max * 内存对线程数量的影响不是直接的。 * 线程栈的最大数值, 不影响线程的数量。 你的总结还是有些问题的。 |
|
返回顶楼 | |
发表时间:2010-03-21
sdh5724 写道 * 调整java thread stack: -Xss256k 需要测试下, 基本来说是足够的. 能降低jvm内存的使用。 * 32位下, 最好不要超过1280M内存。 * 看看 ulimit -u 这个参数. 这是表示用户能拥有的线程数量。 还有OS能拥有的线程也是有限制的: thread-max * 内存对线程数量的影响不是直接的。 * 线程栈的最大数值, 不影响线程的数量。 你的总结还是有些问题的。 总结的过程中,才能有所发现,多谢。 > 32位下, 最好不要超过1280M内存。 你指的是HEAP的大小吧, 事实上我也觉得我的问题正出在此处。目前改为1000,系统还未抛出异常。 再者, 关于Linux max user processes参数, 我用的是系统默认值. 73728 我觉得足够了。 > 线程栈的最大数值, 不影响线程的数量。 线程栈和线程数在内存一定的情况下还是成反比的嗯。 |
|
返回顶楼 | |
发表时间:2010-03-21
最后修改:2010-03-21
下面的文章对java的OOM进行了揭秘,或许对你有所帮助:http://java.sys-con.com/node/1229281
|
|
返回顶楼 | |
发表时间:2010-03-22
嗯, 确实有很大的帮助, 先谢过再阅读
|
|
返回顶楼 | |