java.lang.OutOfMemoryError:无法创建新的本机线程

java.lang.OutOfMemoryError:无法创建新的本机线程

当我尝试在我的 Mac 上运行 Junit 测试时,我总是收到此异常:

java.lang.OutOfMemoryError: unable to create new native thread
        at java.lang.Thread.start0(Native Method)
        at java.lang.Thread.start(Thread.java:658)
        at java.util.concurrent.ThreadPoolExecutor.addIfUnderMaximumPoolSize(ThreadPoolExecutor.java:727)
        at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:657)
        at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:92)
        at com.google.appengine.tools.development.ApiProxyLocalImpl$PrivilegedApiAction.run(ApiProxyLocalImpl.java:197)
        at com.google.appengine.tools.development.ApiProxyLocalImpl$PrivilegedApiAction.run(ApiProxyLocalImpl.java:184)
        at java.security.AccessController.doPrivileged(Native Method)
        at com.google.appengine.tools.development.ApiProxyLocalImpl.doAsyncCall(ApiProxyLocalImpl.java:172)
        at com.google.appengine.tools.development.ApiProxyLocalImpl.makeAsyncCall(ApiProxyLocalImpl.java:138)

同一组单元测试在 ubuntu 和 windows 上都完美通过。

有关我的 Mac 上的系统资源的一些信息:

$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 1
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 266
virtual memory          (kbytes, -v) unlimited

$ java -version
java version "1.6.0_24"
Java(TM) SE Runtime Environment (build 1.6.0_24-b07-334-10M3326)
Java HotSpot(TM) 64-Bit Server VM (build 19.1-b02-334, mixed mode)

我不认为这是应用程序问题,因为相同的测试在不同的环境中都通过了。我尝试将堆设置为 1024m、512m,并将堆栈设置为 64k 和 128k(以及这些组合中的每一个),但没有成功。我打开的文件最初是 256 个,我将其增加到 1024 个。

我在 Google 上搜索了一段时间,所有帖子都说要减少堆大小并增加堆栈大小,但这似乎没有帮助。有人有什么想法吗?

编辑:这是我的 ubuntu 盒子上的一些环境信息:

$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 20
file size               (blocks, -f) unlimited
pending signals                 (-i) 16382
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) unlimited
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

$ java -version
java version "1.6.0_24"
Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
Java HotSpot(TM) 64-Bit Server VM (build 19.1-b02, mixed mode)

答案1

这可能是max user processes你遇到的问题。尝试将其增加到 1024 左右。

ulimit -u 1024

对此存在全局限制,因此请检查sysctl.conf并查看输出:

sysctl kern.maxprocperuid kern.maxproc

并根据需要进行调整。

答案2

为 jvm 分配更多内存。通常这是原因。如果您有 1GB,请添加 0.5GB 或 1。根据您的 RAM,您必须为 OS 进程保留 1-2 GB 的 RAM。不要分配超过您拥有的内存。

正如 Mat 所说,这可能是打开的文件过多的问题,但在这种情况下,您应该会看到这样的消息。在日志中搜索它。

答案3

堆栈大小(kbytes,-s)8192

对于大型多线程应用程序来说,这个值太大了。如果您要运行大量线程,请尝试使用 ulimit -s 或在 /etc/security/limits.conf 中将其设置为 1024

答案4

另一种方法是调整 JVM 堆栈大小,如下所述: 防止“OutOfMemory:无法创建新线程”使用 Javas-Xss非标准选项(另请参阅工具文档

这可能是一个可行的选择,每当您无法控制/减少线程数量时(例如,当罪魁祸首是您不能放弃的第三方库或框架时)

相关内容