Java多线程内存不足

Java多线程内存不足,java,multithreading,memory,jvm,Java,Multithreading,Memory,Jvm,我制作了一个多线程程序,它返回一个内存错误。我已经设置为4000M内存,但它仍然返回内存不足 启动该程序的参数如下所示: /common/packages/8.1.1/java/jdk1.6.0_38/bin/java -jar -d64 -XX:MaxPermSize=4000M -Xms4000M -Xmx4000M batchReserveNumbersReflectStatus.jar 下面是多线程源代码 ThreadPoolExecutor executor; int maxThre

我制作了一个多线程程序,它返回一个内存错误。我已经设置为4000M内存,但它仍然返回内存不足

启动该程序的参数如下所示:

/common/packages/8.1.1/java/jdk1.6.0_38/bin/java -jar -d64 -XX:MaxPermSize=4000M -Xms4000M -Xmx4000M batchReserveNumbersReflectStatus.jar
下面是多线程源代码

ThreadPoolExecutor executor;
int maxThreadQ = 0;
maxThreadQ = 10000;

BlockingQueue queue = new ArrayBlockingQueue(maxThreadQ);
Runnable task=null;

executor = new ThreadPoolExecutor(Integer.parseInt(20),Integer.parseInt(20),2400,TimeUnit.MILLISECONDS, queue);
下面是错误的详细信息

bash-3.2$ tail -200 hs_err_pid2321.log
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (malloc) failed to allocate 5464064 bytes for card table expansion
# Possible reasons:
#   The system is out of physical RAM or swap space
#   In 32 bit mode, the process size limit was hit
# Possible solutions:
#   Reduce memory load on the system
#   Increase physical memory or swap space
#   Check if swap backing store is full
#   Use 64 bit Java on a 64 bit OS
#   Decrease Java heap size (-Xmx/-Xms)
#   Decrease number of Java threads
#   Decrease Java thread stack sizes (-Xss)
#   Set larger code cache with -XX:ReservedCodeCacheSize=
# This output file may be truncated or incomplete.
#
#  Out of Memory Error (cardTableModRefBS.cpp:290), pid=2321, tid=2
#
# JRE version: 6.0_38-b05
# Java VM: Java HotSpot(TM) 64-Bit Server VM (20.13-b02 mixed mode solaris-sparc compressed oops)

---------------  T H R E A D  ---------------

Current thread (0x0000000100117000):  JavaThread "Unknown thread" [_thread_in_vm, id=2, stack(0xffffffff7ba00000,0xffffffff7bb00000)]

Stack: [0xffffffff7ba00000,0xffffffff7bb00000],  sp=0xffffffff7bafec80,  free space=1019k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x9b24ac]  void VMError::report_and_die()+0x75c
V  [libjvm.so+0x514844]  void report_vm_out_of_memory(const char*,int,unsigned long,const char*)+0x64
V  [libjvm.so+0x2ae6b8]  void CardTableModRefBS::resize_covered_region(MemRegion)+0x1c0
V  [libjvm.so+0x2ae348]  void CardTableExtension::resize_covered_region(MemRegion)+0xe8
V  [libjvm.so+0x2c3c44]  void PSOldGen::initialize_work(const char*,int)+0xa4
V  [libjvm.so+0x8a2920]  void PSOldGen::initialize(ReservedSpace,unsigned long,const char*,int)+0xc8
V  [libjvm.so+0x35de58]  AdjoiningGenerations::AdjoiningGenerations #Nvariant 1(ReservedSpace,unsigned long,unsigned long,unsigned long,unsigned long,unsigned long,unsigned long,unsigned long)+0x2a8
V  [libjvm.so+0x2d1d84]  int ParallelScavengeHeap::initialize()+0x4bc
V  [libjvm.so+0x96fc7c]  int Universe::initialize_heap()+0x224
V  [libjvm.so+0x2e0b90]  int universe_init()+0x118
V  [libjvm.so+0x2cea04]  int init_globals()+0xac
V  [libjvm.so+0x95bad0]  int Threads::create_vm(JavaVMInitArgs*,bool*)+0x238
V  [libjvm.so+0x2dc0f4]  JNI_CreateJavaVM+0x74
C  [java+0x2778]
[error occurred during error reporting (printing native stack), id 0xb]


---------------  P R O C E S S  ---------------

Java Threads: ( => current thread )

Other Threads:

=>0x0000000100117000 (exited) JavaThread "Unknown thread" [_thread_in_vm, id=2, stack(0xffffffff7ba00000,0xffffffff7bb00000)]

VM state:not at safepoint (not fully initialized)

VM Mutex/Monitor currently owned by a thread: None

Dynamic libraries:
0x0000000100000000      /common/packages/8.1.1/java/jdk1.6.0_38/bin/sparcv9/java
0xffffffff7f200000      /lib/64/libthread.so.1
0xffffffff7ef00000      /common/packages/8.1.1/java/jdk1.6.0_38/bin/sparcv9/../../jre/lib/sparcv9/jli/libjli.so
0xffffffff7ed00000      /lib/64/libdl.so.1
0xffffffff7e900000      /lib/64/libc.so.1
0xffffffff7f000000      /platform/SUNW,T5240/lib/sparcv9/libc_psr.so.1
0xffffffff7d800000      /common/packages/8.1.1/java/jdk1.6.0_38/jre/lib/sparcv9/server/libjvm.so
0xffffffff7d600000      /lib/64/libsocket.so.1
0xffffffff7e700000      /usr/lib/64/libsched.so.1
0xffffffff7d400000      /lib/64/libm.so.1
0xffffffff7d200000      /usr/lib/64/libCrun.so.1
0xffffffff7d000000      /lib/64/libdoor.so.1
0xffffffff7ce00000      /usr/lib/64/libdemangle.so.1
0xffffffff7cc00000      /lib/64/libkstat.so.1
0xffffffff7ca00000      /lib/64/libnsl.so.1
0xffffffff7c800000      /lib/64/libm.so.2
0xffffffff7c600000      /lib/64/libmp.so.2
0xffffffff7c400000      /lib/64/libmd.so.1
0xffffffff7c200000      /platform/SUNW,T5240/lib/sparcv9/libmd_psr.so.1
0xffffffff7c000000      /lib/64/libscf.so.1
0xffffffff7be00000      /lib/64/libuutil.so.1
0xffffffff7bc00000      /lib/64/libgen.so.1
0xffffffff7b800000      /common/packages/8.1.1/java/jdk1.6.0_38/jre/lib/sparcv9/libverify.so
0xffffffff7b600000      /common/packages/8.1.1/java/jdk1.6.0_38/jre/lib/sparcv9/libjava.so
0xffffffff7b400000      /common/packages/8.1.1/java/jdk1.6.0_38/jre/lib/sparcv9/libzip.so

VM Arguments:
jvm_args: -XX:MaxPermSize=4000M -Xms4000M -Xmx4000M
java_command: batchReserveNumbersReflectStatus.jar
Launcher Type: SUN_STANDARD

Environment Variables:
PATH=/usr/bin:
LD_LIBRARY_PATH=/common/packages/8.1.1/java/jdk1.6.0_38/jre/lib/sparcv9/server:/common/packages/8.1.1/java/jdk1.6.0_38/jre/lib/sparcv9:/common/packages/8.1.1/java/jdk1.6.0_38/jre/../lib/sparcv9
SHELL=/usr/bin/sh

Signal Handlers:
SIGSEGV: [libjvm.so+0x9b3120], sa_mask[0]=0xffbffeff, sa_flags=0x0000000c
SIGBUS: [libjvm.so+0x9b3120], sa_mask[0]=0xffbffeff, sa_flags=0x0000000c
SIGFPE: [libjvm.so+0x23f6b8], sa_mask[0]=0xffbffeff, sa_flags=0x0000000c
SIGPIPE: [libjvm.so+0x23f6b8], sa_mask[0]=0xffbffeff, sa_flags=0x0000000c
SIGXFSZ: [libjvm.so+0x23f6b8], sa_mask[0]=0xffbffeff, sa_flags=0x0000000c
SIGILL: [libjvm.so+0x23f6b8], sa_mask[0]=0xffbffeff, sa_flags=0x0000000c
SIGUSR1: SIG_DFL, sa_mask[0]=0x00000000, sa_flags=0x00000000
SIGUSR2: SIG_DFL, sa_mask[0]=0x00000000, sa_flags=0x00000000
SIGQUIT: SIG_IGN, sa_mask[0]=0x00000000, sa_flags=0x00000000
SIGHUP: SIG_IGN, sa_mask[0]=0x00000000, sa_flags=0x00000000
SIGINT: SIG_IGN, sa_mask[0]=0x00000000, sa_flags=0x00000000
SIGTERM: SIG_DFL, sa_mask[0]=0x00000000, sa_flags=0x00000000
SIG39: [libjvm.so+0x86c2c8], sa_mask[0]=0x00000000, sa_flags=0x00000008
SIG40: [libjvm.so+0x23f6b8], sa_mask[0]=0xffbffeff, sa_flags=0x0000000c


---------------  S Y S T E M  ---------------

OS:                   Oracle Solaris 10 1/13 s10s_u11wos_24a SPARC
  Copyright (c) 1983, 2013, Oracle and/or its affiliates. All rights reserved.
                            Assembled 17 January 2013

uname:SunOS 5.10 Generic_150400-11 sun4v  (T2 libthread)
rlimit: STACK 8192k, CORE infinity, NOFILE 65536, AS infinity
load average:1.28 1.30 1.30

CPU:total 16 has_v8, has_v9, popc, has_vis1, has_vis2, has_blk_init, is_ultra3, is_sun4v, is_niagara, is_niagara_plus

Memory: 8k page, physical 16777216k(8945944k free)

vm_info: Java HotSpot(TM) 64-Bit Server VM (20.13-b02) for solaris-sparc JRE (1.6.0_38-b05), built on Nov 14 2012 00:50:51 by "" with Workshop 5.8

time: Tue Nov  4 14:30:01 2014
elapsed time: 0 seconds
下面是ulimit的结果

bash-3.2$ ulimit -a
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
open files                      (-n) 256
pipe size            (512 bytes, -p) 10
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 2048
virtual memory          (kbytes, -v) unlimited
java版本:

bash-3.2$ java -version -d64
java version "1.6.0_38"
Java(TM) SE Runtime Environment (build 1.6.0_38-b05)
Java HotSpot(TM) 64-Bit Server VM (build 20.13-b02, mixed mode)

我已经检查了其他与此相关的帖子,但在我的案例中仍然不起作用。有什么建议吗?我需要做什么

这不是java.lang.OutOfMemory错误

这个错误是不同的。您耗尽了本机内存。这可能发生在Unix上,它允许您过度提交内存。i、 e.您可以启动一个程序,该程序要求的虚拟内存比实际可用内存多。如果您的程序试图使用所有这些内存,但发现无法使用,例如,您的交换空间用完了,JVM不知道该怎么做,就会崩溃

堆栈跟踪表明是perm gen尝试分配内存,但失败了,但是程序的其他部分可能是关键消费者

您可能会发现,减少perm gen和堆大小将减少您的需求并允许您的程序工作。也可能是由于创建了太多线程,导致内存不足。每个线程分配一个堆栈空间,这也可能耗尽

我建议您在应用程序崩溃后运行top,看看还有多少可用内存。然后我会确保堆、perm-gen和线程堆栈适合这个空间量


简言之,您需要查看您有多少可用的本机内存,并尽量不要使用更多的本机内存。

有许多因素可能会导致本机内存不足,但内存泄漏是最可能的罪魁祸首。尝试减少一点线程,然后看看是否仍然会出现错误。内存泄漏会随着时间的推移而增长,因此线程的减少意味着您将以较慢的速度处理泄漏。相反,更多的线程意味着您可以更快地到达那里,这意味着识别是否是内存泄漏可以更容易地修复它是另一回事。MaxPermSize设置太高,启动java程序时可用的物理ram是多少?自由。@MarshallTigerus我就是这么做的。我尝试从最低内存到4g内存。但仍然有相同的错误。@nomoa物理内存为16gb。6gb已经分配给了其他应用程序。由于有空闲内存,我怀疑一些内核技巧会拒绝malloc jvm请求的5.5Mb。您可以查看系统和内核日志。无论如何,请减少或删除MaxPermSize,不要设置Xms。奇怪的是,日志表明有8g的可用内存:8k页,物理16777216k8945944k空闲。@nomoa所以堆是4G,perm gen是4G,线程堆栈是零。4克的烫发量相当高,我会试着把它缩小一些,比如500米或更少,通常200米就足够了。