欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

linux当前用户最大进程数上限 导致java堆溢出

程序员文章站 2023-12-31 09:04:58
这种堆溢出是在启动线程时抛出。异常信息为unable to create new native thread 栈如下:Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native threadat java.lang.Thread.start0(Native Method)at java.lang.Thread.start(Thread.java:717)at jdk.nashorn.int...
  • 此文使用user表示Linux用户名

这种堆溢出是在启动线程时抛出。异常信息为unable to create new native thread 栈如下:

Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
	at java.lang.Thread.start0(Native Method)
	at java.lang.Thread.start(Thread.java:717)
	at jdk.nashorn.internal.scripts.Script$1$\^shell\_.:program(<shell>:1)
	at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:637)
	at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:494)
	at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
	at jdk.nashorn.internal.runtime.Context.eval(Context.java:738)
	at jdk.nashorn.internal.runtime.Context.eval(Context.java:673)
	at jdk.nashorn.tools.Shell.readEvalPrint(Shell.java:516)
	at jdk.nashorn.tools.Shell.run(Shell.java:168)
	at jdk.nashorn.tools.Shell.main(Shell.java:143)
	at jdk.nashorn.tools.Shell.main(Shell.java:119) 

触发原理,在linux操作系统中,创建足够多线程,使当前用户在当前会话的子进程数量达到上限,再创建新线程便可触发。

查看和设置当前用户最大进程数

查看 ulimit -a 执行结果如下:

[user@localhost ~]$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 190703
max locked memory       (kbytes, -l) 16384
max memory size         (kbytes, -m) unlimited
open files                      (-n) 40960
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) 40960
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimite 

-a 即查看所有限制项。单独查看当前用户最大进程数则是 ulimt -u

给当前用户设置的上限的方法,直接在命令行上执行 ulimit -u 10000 。当前用户在命令行的方式设置的值只能小于等于设置之前的值。设置完立即生效,只影响当前会话。

也可以通过root用户修改 /etc/security/limits.conf 中 用户 nproc 项 根据其中注释样例和已有配置即可。(在CentOs和eulerosv2r7.x86_64 会有一个单独的 /etc/security/limits.d/20-nproc.conf文件,用来配置nproc,非root用户默认4096。修改文件的设置方法会在用户重新登录后生效。)

触发方法
  • 查看最大进程数ulimit -u,统计已创建的子进程数, ps -efL | grep 当前用户名 | wc -l

    user@localhost:~> ulimit -u
    40960
    user@localhost:~> ps -efL | grep user| wc -l
    679 
  • 根据上述查询结果设置一个较小容易达到的上限,当前已创建679,将上限降低更容易复现,此处将当前会话的最大进程数设置为1000 ulimit -u 1000

  • 可以使用java代码用循环创建线程即可,此处为了省去编译,采用jre目录下的jjs程序代替java。

    检查jre/bin目录有没有在path中,没有则 export PATH=$PATH:/${jrePath}/bin,后执行jjs

    会打印一个类似于python或者 nodejs交互式命令行

    user@localhost:~> jjs
    jjs> 

    往交互式命令行输入,以下两行js语句,用来循环创建线程。(触发前最好新开一个ssh会话)

    输入以下语句后回车。

    //直接将类名赋值给变量即可 Th = java.lang.Thread //当前语句在jjs交互式命令行,需要单行输入 for (var i = 0; i < 400; i++) { new Th(function () { print(Th.currentThread().getName());Th.sleep(500000); }).start(); } 

    不出意外会发生堆溢出,且当前会话的终端无法继续交互,待休眠结束,线程释放终端可以被释放。

本文地址:https://blog.csdn.net/qq_26700087/article/details/108867434

相关标签: java linux

上一篇:

下一篇: