论坛首页 Java企业应用论坛

理解OutOfMemoryError: unable to create new native thread

浏览 26237 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-10-24   最后修改:2009-10-24
OO
最近碰着了java.lang.OutOfMemoryError: unable to create new native thread,籍由这个机会尝试深入理解这个问题。

原因是创建过多thread引出的问题,JVM此时无法再创建出更多的线程。这里的解释还是比较靠谱的

引用
As you can see, the maximum number of threads I can create decreases as the heap size gets larger. This is because the JVM immediately reserves the address space specified for the maximum heap size - That's probably because it needs that memory to be contiguous
.
表象便是当JVM的heap size设置过大时,thread的创建数量便会减少。这里找到了一个还算清晰的说明

引用
Maximum heap size depends on maximum address space per process.
Maximum heap space is always smaller than maximum address space per process, because the process also needs space for stack, libraries, and so on.


JVM的堆和进程所需的栈都会消耗进程地址空间(address space),而地址空间则取决于操作系统,Windows中

引用
所有 32 位应用程序都有 4 GB 的进程地址空间(32 位地址最多可以映射 4 GB 的内存)。对于 Microsoft Windows 操作系统,应用程序可以访问 2 GB 的进程地址空间,称为用户模式虚拟地址空间。应用程序拥有的所有线程都共享同一个用户模式虚拟地址空间。其余 2 GB 为操作系统保留(也称为内核模式地址空间)。


目前我的理解是,JVM申请的heap会占用相同大小的地址空间(address space)。在Windows 32位操作系统中,分配给每个程序的地址空间只有2GB(当然也有3GB的开关)。而每个不同的JVM的堆和其创建的进程栈都依赖于同一个进程地址空间,所以这也是此消彼长的原因。

有方法可以提高创建线程的数量:
1.减少JVM的heap size;
2.减少单个线程栈的大小,在JVM启动中使用-Xss参数。目前JDK1.4中每个线程栈所大小是256K,1.5是1M.

唉,大学的操作系统课程荒废了,地址空间也有些拎不清了。
   发表时间:2009-11-02  

thanks for sharing

这个应该是Windows的限制

http://java.sun.com/docs/hotspot/HotSpotFAQ.html#gc_heap_32bit

Why can't I get a larger heap with the 32-bit JVM?

The maximum theoretical heap limit for the 32-bit JVM is 4G. Due to various additional constraints such as available swap, kernel address space usage, memory fragmentation, and VM overhead, in practice the limit can be much lower. On most modern 32-bit Windows systems the maximum heap size will range from 1.4G to 1.6G. On 32-bit Solaris kernels the address space is limited to 2G. On 64-bit operating systems running the 32-bit VM, the max heap size can be higher, approaching 4G on many Solaris systems.

As of Java SE 6, the Windows /3GB boot.ini feature is not supported.

JVM占用的内存包括Stack, Heap等。但是只有Heap是可以设置的。如果windows只能给每个应用程序分配2G内存,那么heap也不能使用全部,Stack要占用一部分。Solaris就没有这个问题。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics