请参考英语答案
Java : unabletocreatenewnativethread 6
我们有广泛部署的APP应用。 数百个工作站正在运行它。 一个网站(只有一个网站。 我们的产品被广泛部署在很多环境中。 )我们随机得到了以下错误。
java.lang.OutOfMemoryError :无法创建新的本机线程
在java.lang.Thread.start0(本机方法)中
在java.lang.Thread.start (未知来源)上
操作系统为Windows 7 64位
我们正在运行32位JVM(1.7.0_45 )
使用Windows任务管理器,可以看到此进程有39个本机线程。 不是很多。 因此,我们的APP应用程序没有线程泄漏…其他进程没有占用大量线程。 (Explorer为35,jvisualvm为24,iexplore为20,…虽然没有确切的数量,但您可以看到可能占用300个线程的用户总数。
试图添加JVisualVM,但无法连接到进程。 恐怕乙/丙线程已耗尽。 但是,根据JVisualVM提供的指标,Java线程的数量约为22个活动和11个守护进程。
堆的动作很好。 堆为500MB,实际使用的是250MB。
此过程以-Xmx512m开始
我们的进程显示了597,744 k的内存使用情况。
此工作站有8GB内存,其中只有3.8-4.0GB。 (虽然一个32位进程并不能访问所有这些,但我知道还有很多。 )
要使用的虚拟机映射。 堆栈的大小为49,920 kb,约定为2,284 k。
该过程显示5358KB是免费的,免费列表中最大的可分配块大小为1,1024 k。
使用资源监视器。 其提交(KB )为630428,工作集(KB )为676,996,可共享(KB )为79,252,私人(KB )为597,744
我完全失去了这里发生了什么。 我读了很多文章,这是一些Linux系统,听起来每个用户的线程限制可能会引起问题。 (但这不是Linux,其他文章中介绍的问题通常需要几千个线程。 绝对不是我们的情况。 )
如果我们的堆很大,可以看到线程可以使用的访问空间,但500MB似乎是非常合理的小堆。 特别是具有8gb ram的工作站。
所以我把知道的都花光了。 有谁能在这里做什么吗?
编辑1 :
他们建议堆栈大小可能是个问题。
正文: wheretofinddefaultxssvalueforsun/Oracle JVM? 提供指向Oracle文档的链接,指示默认堆栈大小为512KB。 因此,如果APP应用程序有大约40个线程,则检查的是20 MB堆栈. 500MB的堆。 这似乎完全符合32位Java进程的正常范围。
所以我有两个可能的想法:
一些临时条件导致创建大量线程。 但是,在有机会接受诊断之前,这些线程将被销毁)。
有趣的是,内存碎片出于某种原因杀死了我们,最大的可分配块(每个虚拟机映射1MB )看起来并不多…在另一台机器上正常工作,最大的可分配块是470MB …
那么,有关于如何检查内存段的指针吗?
编辑2 :
我来承担:
操作系统进程空间限制: 2GB
现代JVM需要250MB。 (这是个很大的假设。 只是将链接到的文章的内容翻了一番) ) ) )。
堆栈大小(默认Oracle ) 512KB
堆: 512MB
PermGen : (虽然我完全不记得,但肯定不到100MB,用一下这个吧)。
我有最坏的情况。 (2gb. 25gb. 5gb. 1gb )/.005GB=230个线程
编辑3 :
信息应该包括在出现此问题之前APP应用程序正常运行(例如24~48小时)。 此APP应用程序执行连续的后台处理,因此空闲时间较少。 是否重要还不确定
编辑4 :
详细信息:从另一个失败中查看虚拟机映射,可以看到本地堆已耗尽。
堆的大小为1.2GB,只有59.8MB的约定。
Java运行时是这里的问题,可能是本机资源没有正确发布的问题吗? 可能是未释放的内存映射文件吗?
因为正在使用内存映射文件,所以重点放在它们上。
编辑4 :
我想我把问题追踪到了例外,发生了以下事情。
java.lang.OutOfMemoryError
at Java.util.zip.deflater.init (朴素方法) )。
at Java.util.zip.deflater.(unknown source )
at Java.util.zip.deflater.(unknown source )
at Java.util.zip.deflateroutputstream.(unknown source )
at Java.util.zip.deflateroutputstream.(unknown source )
at .
一些非常少量的流(我现在有四个例子)我们放气,如上所述发生。 当发生这种情况时,VMMap会将进程堆栈(实际的本地堆栈,而不是JVM堆栈)设置为最多2GB。 一旦发生这种情况,一切都会崩溃。 现在非常可重复) )执行相同的流程进入deflater,导致内存尖峰)。
那么,我可以看看JRE的zip库的问题吗? 看起来很疯狂,我想是的,但我真的很消沉。
如果使用完全相同的流并在不同的系统上运行,则运行相同的JRE32位Java 7u45没有问题。 已完全卸载JRE,并在不更改其行为的情况下重新安装。