首页 > 解决方案 > 为什么这个异常在我的服务器上运行 Spring Boot\Batch 应用程序?java.lang.OutOfMemoryError:无法创建本机线程:

问题描述

我正在开发 SpringBoot\Spring Batch 应用程序。我在我的开发机器上测试了它,我发现没有问题。它工作正常。当我尝试在生产机器上部署它时,问题就发生了。

首先我要说的是,我现在以这种简单的方式在这台 prod 机器上安装了 Oracle Java 17:我只从这里下载了 Oracle Java 17 SE的tar.gx版本: https ://www.oracle.com/ java/technologies/javase/jdk17-archive-downloads.html

我在这台 Linux Centos 7 机器上解压它,然后进入bin文件夹,我可以执行 java 命令:

webadmin@webadmin.xxx.it [~/java/jdk-17.0.1/bin]# pwd
/home/webadmin/java/jdk-17.0.1/bin
webadmin@webadmin.xxx.it [~/java/jdk-17.0.1/bin]# ./java -version
java version "17.0.1" 2021-10-19 LTS
Java(TM) SE Runtime Environment (build 17.0.1+12-LTS-39)
Java HotSpot(TM) 64-Bit Server VM (build 17.0.1+12-LTS-39, mixed mode, sharing)
webadmin@webadmin.xxx.it [~/java/jdk-17.0.1/bin]#

我不确定它是否完全正确,但直到现在它似乎有效,因为我正在获取 Java 版本作为输出。

然后我尝试以这种方式执行我的 Spring Boot\Spring Batch 应用程序:

webadmin@webadmin.xxx.it [~/java/jdk-17.0.1/bin]# ./java -jar /home/webadmin/notartel-import-data-batch/UpdateInfoBatch-0.0.1-SNAPSHOT.jar

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.5.3)

2021-11-14 11:27:04.878  INFO 23288 --- [           main] c.n.u.UpdateInfoBatchApplication         : Starting UpdateInfoBatchApplication v0.0.1-SNAPSHOT using Java 17.0.1 on c00lc5-notariato.sphostserver.com with PID 23288 (/home/webadmin/notartel-import-data-batch/UpdateInfoBatch-0.0.1-SNAPSHOT.jar started by webadmin in /home/webadmin/java/jdk-17.0.1/bin)
2021-11-14 11:27:04.880  INFO 23288 --- [           main] c.n.u.UpdateInfoBatchApplication         : No active profile set, falling back to default profiles: default
2021-11-14 11:27:06.759  INFO 23288 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2021-11-14 11:27:06.783  INFO 23288 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2021-11-14 11:27:06.783  INFO 23288 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.50]
2021-11-14 11:27:06.831  INFO 23288 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2021-11-14 11:27:06.831  INFO 23288 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1898 ms
[2.997s][warning][os,thread] Failed to start thread - pthread_create failed (EAGAIN) for attributes: stacksize: 1024k, guardsize: 0k, detached.
[2.998s][warning][os,thread] Failed to start thread - pthread_create failed (EAGAIN) for attributes: stacksize: 1024k, guardsize: 0k, detached.
[3.001s][warning][os,thread] Failed to start thread - pthread_create failed (EAGAIN) for attributes: stacksize: 1024k, guardsize: 0k, detached.
2021-11-14 11:27:07.013  WARN 23288 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is java.lang.OutOfMemoryError: unable to create native thread: possibly out of memory or process/resource limits reached
2021-11-14 11:27:07.028  INFO 23288 --- [           main] ConditionEvaluationReportLoggingListener :

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-11-14 11:27:07.046 ERROR 23288 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is java.lang.OutOfMemoryError: unable to create native thread: possibly out of memory or process/resource limits reached
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:163) ~[spring-boot-2.5.3.jar!/:2.5.3]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:577) ~[spring-context-5.3.9.jar!/:5.3.9]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) ~[spring-boot-2.5.3.jar!/:2.5.3]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-2.5.3.jar!/:2.5.3]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434) ~[spring-boot-2.5.3.jar!/:2.5.3]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:338) ~[spring-boot-2.5.3.jar!/:2.5.3]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) ~[spring-boot-2.5.3.jar!/:2.5.3]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1332) ~[spring-boot-2.5.3.jar!/:2.5.3]
        at com.notariato.updateInfo.UpdateInfoBatchApplication.main(UpdateInfoBatchApplication.java:42) ~[classes!/:0.0.1-SNAPSHOT]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49) ~[UpdateInfoBatch-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:108) ~[UpdateInfoBatch-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) ~[UpdateInfoBatch-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88) ~[UpdateInfoBatch-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
Caused by: java.lang.OutOfMemoryError: unable to create native thread: possibly out of memory or process/resource limits reached
        at java.base/java.lang.Thread.start0(Native Method) ~[na:na]
        at java.base/java.lang.Thread.start(Thread.java:802) ~[na:na]
        at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.startDaemonAwaitThread(TomcatWebServer.java:203) ~[spring-boot-2.5.3.jar!/:2.5.3]
        at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:137) ~[spring-boot-2.5.3.jar!/:2.5.3]
        at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:104) ~[spring-boot-2.5.3.jar!/:2.5.3]
        at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:450) ~[spring-boot-2.5.3.jar!/:2.5.3]
        at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:199) ~[spring-boot-2.5.3.jar!/:2.5.3]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:182) ~[spring-boot-2.5.3.jar!/:2.5.3]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:160) ~[spring-boot-2.5.3.jar!/:2.5.3]
        ... 16 common frames omitted

如您所见,我正在尝试执行我的 jar 文件,但我得到了这个异常:

Caused by: java.lang.OutOfMemoryError: unable to create native thread: possibly out of memory or process/resource limits reached

所以,因为在我的开发机器上它工作正常(而且我使用的是我的开发机器的相同 Java 版本)我想它应该是一些 JVM 配置或类似的东西。但是什么?

我试图探索这里显示的内容:http: //www.mastertheboss.com/jbossas/monitoring/how-to-solve-javalangoutofmemoryerror-unable-to-create-new-native-thread/

但是我在这台机器上没有 root 访问权限,所以我不能执行很多检查。使用此 webadmin 用户为我提供输出的唯一检查是与当前正在运行的线程数相关的检查,这一项:

webadmin@webadmin.xxx.it [~/java/jdk-17.0.1/bin]# cat /proc/loadavg
0.15 0.27 0.30 1/365 23666

以及每个用户的进程数:

webadmin@webadmin.xxx.it [~/java/jdk-17.0.1/bin]# ulimit -a
core file size          (blocks, -c) 200000
data seg size           (kbytes, -d) 200000
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 128613
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) 200000
open files                      (-n) 100
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) 35
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

这是应该显示正在运行的进程数的命令:

webadmin@webadmin.xxx.it [~/java/jdk-17.0.1/bin]# ps -elfT | wc -l
365

我不知道这些最后的系统信息是否与这个特定问题有关。

为什么我得到这个错误?我可以尝试做些什么来解决这个问题?或者我有什么要请教处理这台服务器的系统工程师来改变?

标签: javaspringspring-bootspring-batchjava-17

解决方案


最大用户进程 (-u) 35

这似乎真的很低。您应该检查您的用户当前运行的进程数量 - 对我来说,异常似乎表明已达到此限制。因此,具有管理员权限的人需要增加用户进程限制。

另外,这个:

最大内存大小 (kbytes, -m) 200000

对于Java应用程序来说也不是很多。您总共只能获得 200M,这对于大多数 Java Web 应用程序来说是不够的。

您的生产帐户似乎配置为非常少的资源,这要么需要增加,要么您需要更改应用程序的方法并开始为低资源环境而不是常规环境开发它。


推荐阅读