0 java multithreading out-of-memory
我在64位Windows 7和带有64位JVM的Server 2008中运行,并且在具有大量可用内存的程序中得到"java.lang.OutOfMemoryError:无法创建新的本机线程".我已经阅读了关于垃圾收集和堆生成等等,但似乎没有解释这种情况.我最接近的是一个条目,它给出了一个分配空闲线程的程序(如何通过生成线程来命中java.lang.OutOfMemoryError?根据Ajay George的反应)并至少重新创建我们的生产代码中存在的问题.问题是,当我们使用-XX:+ HeapDumpOnOutOfMemoryError运行时,我们得到OOM有足够的OS内存(RAM)可用,很少在堆中分配,并且没有对OOM异常的响应.当使用小堆设置(Xmx16M)和大堆栈设置(Xss1G)运行上面的代码(空闲线程spawner)时,java进程在失败之前分配大约8179个线程,并且在任务管理器中查看时具有大的提交大小,但是其他它声称资源很少.
我已经启用了GC跟踪,并且在失败之前观察到非常少的活动(通常是两个GC).我已经提升了PermGen无济于事.我将初始堆大小提升到了在故障之前没有消耗的点(Xms1024M Xmx65536M)并且它仍然获得了OOM.
我已经使用YourKit分析器查看了这两个,它显示了我怀疑的内容,即没有消耗堆,并且发生了很少的GC.
然而,我在生产中遇到的问题只有大约150-300个线程(它变化),当它失败并且堆栈大小是默认的,因此在Windows中可能只有1M.
我想要找出的是如何确定导致问题的原因,以便我可以对代码进行适当的更改.
在创建具有非常有限的内存源的线程时,JVM是否有特殊之处?我知道,对于NIO和内存映射文件,JVM不跟踪后台内存备份,内存映射中的高级别流失将很快耗尽内存,但在这种情况下,操作系统显示JVM使用内存.在我们的线程案例中,操作系统将JVM显示为正在使用少量内存.
java.lang.OutOfMemoryError: unable to create new native thread
Run Code Online (Sandbox Code Playgroud)
我想要找出的是如何确定导致问题的原因,以便我可以对代码进行适当的更改.
您的堆栈内存不足,无法分配更多线程.也可能是因为操作系统允许的最大进程数不足,但我不确定Windows是否有这样的限制.
默认情况下,在64位JVM中,每个线程的堆栈大小为1M,并且JVM为线程堆栈分配了最大空间.你当然不希望做一些像-Xss1G每个线程一样gigabyte的东西.您可能会尝试-Xss128k降低每线程内存,但这看起来像是一个绑定.请参阅此页:调整Java默认线程堆栈大小以节省内存
解决此问题的更好方法是使用固定大小的线程池限制创建的线程数,而不是为每个作业分配线程.这很大程度上取决于您的架构.如果您正在处理Web请求,则固定线程池将限制并发连接数,但可能会增加您的总吞吐量.
请参阅Oracle的Thread Pools教程.
问题是我们得到了具有大量OS内存(RAM)的OOM.
是的,这些是由JVM控制的非常具体的限制.这不是堆内存,JVM也不会增长以占用盒子上的所有内存.
看到这些链接:
| 归档时间: |
|
| 查看次数: |
415 次 |
| 最近记录: |