Java内存错误:无法创建新的本机线程

Joe*_*oel 25 java linux memory debian multithreading

运行我的java服务器时,我的UNIX服务器上出现此错误:

Exception in thread "Thread-0" java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Thread.java:640)
at [... where ever I launch a new Thread ...]
Run Code Online (Sandbox Code Playgroud)

每次我运行大约600个线程时都会发生这种情况.

我在服务器上设置了这个变量:

$> ulimit -s 128
Run Code Online (Sandbox Code Playgroud)

我觉得奇怪的是这个命令的结果,我在上次发生错误时运行了这个命令:

$> free -m
              total       used       free     shared    buffers     cached
Mem:          2048        338       1709          0          0          0
-/+ buffers/cache:        338       1709
Swap:            0          0          0
Run Code Online (Sandbox Code Playgroud)

我像这样启动我的java服务器:

$> /usr/bin/java -server -Xss128k -Xmx500m -jar /path/to/myJar.jar
Run Code Online (Sandbox Code Playgroud)

我的debian版本:

$> cat /etc/debian_version
5.0.8
Run Code Online (Sandbox Code Playgroud)

我的java版本:

$> java -version
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)
Run Code Online (Sandbox Code Playgroud)

我的问题:我已经在互联网上看到我的程序应该处理类似5000线程的东西.那么发生了什么,以及如何解决?


编辑:这是ulimit -a我打开shell时的输出:

core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 794624
max locked memory       (kbytes, -l) 32
max memory size         (kbytes, -m) unlimited
open files                      (-n) 100000
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 794624
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
Run Code Online (Sandbox Code Playgroud)

我从init.d运行脚本作为守护进程,这就是我运行的:

DAEMON=/usr/bin/java
DAEMON_ARGS="-server -Xss128k -Xmx1024m -jar /path/to/myJar.jar"
ulimit -s 128 && ulimit -n 10240 && start-stop-daemon -b --start --quiet --chuid $USER -m -p $PIDFILE --exec $DAEMON -- $DAEMON_ARGS \
    || return 2
Run Code Online (Sandbox Code Playgroud)

Edit2:我遇到了这个用于线程的java测试的堆栈溢出问题:how-many-threads-can-a-java-vm-support

    public class DieLikeADog { 
        private static Object s = new Object(); 
        private static int count = 0; 
        public static void main(String[] argv){ 
            for(;;){ 
                new Thread(new Runnable(){ 
                        public void run(){ 
                            synchronized(s){ 
                                count += 1; 
                                System.err.println("New thread #"+count); 
                            } 
                            for(;;){ 
                                try { 
                                    Thread.sleep(100); 
                                } catch (Exception e){ 
                                    System.err.println(e); 
                                } 
                            } 
                        } 
                    }).start(); 
            } 
        } 
    } 
Run Code Online (Sandbox Code Playgroud)

在我的服务器上,程序在613个线程后崩溃.现在我确定这不正常,只与我的服务器配置有关.有人可以帮忙吗?


编辑3:我遇到过这篇文章和其他许多人,他们解释说linux无法创建1000个线程,但是你们告诉我你可以在你的系统上做到这一点.我不明白.

我还在我的服务器上运行了这个脚本:threads_limits.c,限制大约是620个线程.

我的网站现在处于脱机状态,这是我的项目可能发生的最糟糕的事情.我不知道如何重新编译glibc和这些东西.这是太多的工作imo.

我想我应该切换到Windows服务器.因为此页面上提出的所有设置都没有做出任何更改:无论涉及哪个程序,我的系统限制都在600到620个线程之间.

Joe*_*oel 12

刚收到以下信息:这是我的主机提供商施加的限制.这与编程或linux无关.

  • 答案如下:Nuxit.com主机提供商以"专用服务器"的名称销售虚拟服务器.他们使用名为"Parallels®VirtuozzoContainers"的软件虚拟化虚假服务器.它们可以控制进程的运行方式,并对线程,内存等施加限制.我花了一个星期才发现,但我已经改变了主机,现在我的程序终于正常了. (4认同)
  • @Joel:我无法在Amazon EC2计算机上为每个进程创建超过375个线程.这是亚马逊强加的限制吗?https://forums.aws.amazon.com/thread.jspa?threadID=86751 (4认同)
  • 我很确定这个限制是由亚马逊强加的.如果您需要更多线程,请租用真正的专用服务器,而不是虚拟专用服务器或云.您也可以尝试联系他们的支持并要求更多线程插槽.祝好运. (2认同)

esa*_*saj 7

底层操作系统(在本例中为Debian Linux)不允许进程创建更多线程.请参见此处如何提高最大数量:Linux中每个进程的最大线程数?

我在互联网上看到我的程序应该处理大约5000个线程的东西.

这取决于为操作系统设置的限制,正在运行的进程数量等.通过正确的设置,您可以轻松访问许多线程.我在自己的计算机上运行Ubuntu,我可以创建大约32000个线程,然后在单个Java程序上达到限制,所有"正常的东西"都在后台运行(这是通过一个刚创建线程的测试程序完成的在无限循环中立即进入睡眠状态).当然,实际上做大量的线程可能会让消费者的硬件很快停止运转.