![java.lang.OutOfMemoryError:无法创建新的本机线程](https://linux22.com/image/549648/java.lang.OutOfMemoryError%EF%BC%9A%E6%97%A0%E6%B3%95%E5%88%9B%E5%BB%BA%E6%96%B0%E7%9A%84%E6%9C%AC%E6%9C%BA%E7%BA%BF%E7%A8%8B.png)
当我尝试在我的 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
非标准选项(另请参阅工具文档)
这可能是一个可行的选择,每当您无法控制/减少线程数量时(例如,当罪魁祸首是您不能放弃的第三方库或框架时)