2009年9月25日 星期五

Why!? java.lang.OutOfMemoryError: unable to create new native thread

最近在開發系統遇到了一個奇怪的問題,明明都已經把heap space 都調到1024Mb了,怎麼還是會OutOfMemory呢? 仔細看原因居然是unable to create new native thread ,這到底該如何解決呢?


參考一下資料:
How to fix "java.lang.OutOfMemoryError: unable to create new native thread"

This formula gives a decent estimate for the number of threads you can create:
(MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads

For Java 1.5 I get the following results assuming that the OS reserves about 120MB:
1.5GB allocated to JVM: (2GB-1.5Gb-120MB)/(1MB) = ~380 threads
1.0GB allocated to JVM: (2GB-1.0Gb-120MB)/(1MB) = ~880 threads

Java 1.4 uses 256kb for the thread stack which lets you create a lot more threads:
1.5GB allocated to JVM: ~1520 threads
1.0GB allocated to JVM: ~3520 threads

Java Virtual Machine (JVM) - Re: java.lang.OutOfMemoryError: unable to create new native thread

Java Performance Part III - When 4294967296 bytes of address space isn't enough

這篇提到怎樣的heap size 可以產生多少的Thread,參考[Thread Stack Size]
JDK1.4
-Xmx750 = 4580 threads.
-Xmx1000 = 3608 threads.
-Xmx1500M = 1663 threads

JDK1.5
-Xmx750M = 1129 threads
-Xmx1000M = 880 threads
-Xmx1500M = 384 threads

也就是你Heap Space 調得越大,所可以用到的thread 數量就越少?

用來監控沒有啟動的Thread的方法

However, you can put a logic in your application to watch the number of unstarted threads. If this number is growing, you know that somewhere in your application threads are created without the start() calls. Here is the code to calculate the number of unstarted threads:

ThreadGroup g = Thread.currentThread().getThreadGroup();
while (g.getParent()!=null) g = g.getParent();
Thread[] l = new Thread[g.activeCount()]];
int unstartedThreadCount = g.activeCount() - g.enumerate(l,true):
張貼留言