如何解决Java错误“pool-1-thread-xxxx”java.lang.OutOfMemory

我已经搜索了关于这个问题的post,但我没有看到像我这样的情况。

我的java控制台显示错误消息"pool-1-thread-xxxx" java.lang.OutOfMemory如下图所示:

pool-1-thread-OutOfMemoryError issuse

性能监视器

  • 红线:CPU使用率
  • 绿线:内存使用情况

我已将RAM从6G增加到10G ,并在启动程序之前在*.bat文件中设置-Xms=8G -Xmx=8G -Xmn=3G 。 我也一直在观看性能监视器,但内存总是在20%左右。 我不知道怎么会发生这种情况。 任何的想法?

这是我的run.bat代码。

 @echo off javapro @java -Xoptimize -Xms8G -Xmx8G -Xmn3G -Xss1024k -XX:+UseConcMarkSweepGC -cp javaPro.exe; cls run.bat 
  • 操作系统:Windows Server 2012 R2
  • Java版本:jre1.8.0_171
  • RAM:10G
  • CPU:2.5 GHz Intel Xeon(R)(超线程)

错误消息java.lang.OutOfMemoryError: unable to create new native thread意味着

JVM要求来自操作系统的新线程,底层操作系统不能再分配新线程。

请参阅OOM说明并解释 您的具体案例 。

因此,您不会在图中看到高内存使用量,因为堆大小不接近其限制。

您必须检查您的应用程序代码并检查那里的线程池使用情况。 没有源代码很难说什么,但可能没有什么建议:

  1. 如果您使用CachedThreadPoolExecutor ,则提交的任务可能不够快,因此您的应用无法处理所有提交的任务。
  2. 您可以将FixedThreadPoolExecutor与最大( Integer.MAX_VALUE )容量一起使用,在这种情况下,您必须限制池容量及其队列大小。 因此,池会占用所有可用线程并发生OOM

通常,您应始终控制线程池配置,并确保它不会占用所有系统资源。

认为我找到了可能的原因/解决方案方法:

可以使用ulimit -a检查进程的软限制:

 $ cat /proc/22666/limits | grep processes Max processes 1024 62265 processes $ ulimit -a | grep processes max user processes 

为了改变这些值:

 $ ulimit -Su 2000 $ ulimit -a | grep processes max user processes (-u) 2000 $ cat /proc/22666/limits | grep processes Max processes 2000 

一个人也可以调整默认配置:

  1. 使用以下命令修改limits.conf文件:

  2. sudo nano /etc/security/limits.conf或查看/etc/security/limit.d/

  3. 为运行java的用户添加以下内容。

limits.conf中

 #    # adjust these values as needed: someuser soft nofile 4096 someuser hard nofile 8192 

然后使用以下命令修改common-session文件:

 sudo nano /etc/pam.d/common-session 

添加以下行:

普通会话

 session required pam_limits.so 

并重启java。

  • 另见ThreadPoolExecutor ……
  • 和ThreadPoolExecutor配置 。

对于Windows 2012 Server,这将大致相同。

  • 请参阅Tech Net博客上推动Windows的限制 。