简体   繁体   English

Java Out of Memory Error(本机内存),进程大小限制被命中(32位linux)

[英]Java Out of Memory Error(Native memory), the process size limit was hit(32-bit linux)

I am testing the performence of a web application, and have got "Out of Memory Error"(native memory). 我正在测试Web应用程序的性能,并且出现“Out of Memory Error”(本机内存)。

I have test several times, and every time it "failed to allocate 83886088 bytes for Chunk::new" and died. 我已多次测试,每次“未能为Chunk :: new分配83886088字节”而死亡。

I print the memory size every minute, and found that the VmSize was 2924700 kB before the process died. 我每分钟打印一次内存大小,发现VmSize在进程死亡之前是2924700 kB。

I think that the process size limit was hit. 我认为流程大小限制受到了影响。 I change -Xmx2000m to -Xmx1900m and it's OK now. 我将-Xmx2000m更改为-Xmx1900m,现在就可以了。

Some questions: 一些问题:

1.How to comfirm that the process size limit was hit. 1.如何确认流程大小限制被打中。 It's not exactly 3G memory. 这不完全是3G内存。

2.Why JVM allocate 83886088 bytes memory every time? 2.为什么JVM每次分配83886088字节的内存? From the exception stack, it seems that it's related to GC things. 从异常堆栈看,它似乎与GC有关。

3.How many memory should be reserved for JVM besides heap memory(-Xmx) and non-heap memory(-XX:MaxPermSize)? 3.除了堆内存(-Xmx)和非堆内存(-XX:MaxPermSize)之外,应该为JVM保留多少内存? And how to know how many it's using now? 如何知道它现在使用了多少?

Thanks and sorry for my poor English. 谢谢,抱歉我的英语不好。

Linux 2.6.16.60-0.83.2-bigsmp JRE 6.0_25-b06 Tomcat 7.0.37 Linux 2.6.16.60-0.83.2-bigsmp JRE 6.0_25-b06 Tomcat 7.0.37

jvm options: -Xms2000m -Xmx2000m -XX:PermSize=256M -XX:MaxPermSize=512m -XX:+UseConcMarkSweepGC -XX:+UseParNewGC

/proc/meminfo:
MemTotal:     24935548 kB
MemFree:      13564968 kB

# Native memory allocation (malloc) failed to allocate 83886088 bytes for Chunk::new
# Possible reasons:
#   The system is out of physical RAM or swap space
#   In 32 bit mode, the process size limit was hit
...
# This output file may be truncated or incomplete.
#
#  Out of Memory Error (allocation.cpp:317), pid=18217, tid=275671968

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

Current thread (0x105a1c00):  VMThread [stack: 0x10666000,0x106e7000] [id=18243]

Stack: [0x10666000,0x106e7000],  sp=0x106e5ae0,  free space=510k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x724710]  VMError::report_and_die()+0x2b0
V  [libjvm.so+0x2f68ef]  report_vm_out_of_memory(char const*, int, unsigned, char const*)+0x4f
V  [libjvm.so+0x1576fc]  Chunk::operator new(unsigned, unsigned)+0x5c
V  [libjvm.so+0x157c26]  Arena::grow(unsigned)+0x26
V  [libjvm.so+0x6457e9]  resource_allocate_bytes(unsigned)+0x49
V  [libjvm.so+0x3a03ef]  GenericGrowableArray::raw_allocate(int)+0xbf
V  [libjvm.so+0x3402ee]  GrowableArray<oopDesc*>::grow(int)+0x3e
V  [libjvm.so+0x3a62b1]  FindInstanceClosure::do_object(oopDesc*)+0x51
V  [libjvm.so+0x2ae571]  CompactibleFreeListSpace::object_iterate(ObjectClosure*)+0x51
V  [libjvm.so+0x38d066]  GenerationObjIterateClosure::do_space(Space*)+0x16
V  [libjvm.so+0x2d6498]  ConcurrentMarkSweepGeneration::space_iterate(SpaceClosure*, bool)+0x18
V  [libjvm.so+0x38be22]  Generation::object_iterate(ObjectClosure*)+0x22
V  [libjvm.so+0x2d9f9d]  ConcurrentMarkSweepGeneration::object_iterate(ObjectClosure*)+0x4d
V  [libjvm.so+0x37fd65]  GenCollectedHeap::object_iterate(ObjectClosure*)+0x55
V  [libjvm.so+0x3a61fe]  HeapInspection::find_instances_at_safepoint(klassOopDesc*, GrowableArray<oopDesc*>*)+0x3e
V  [libjvm.so+0x6eca91]  ConcurrentLocksDump::dump_at_safepoint()+0xf1
V  [libjvm.so+0x6e7561]  Threads::print_on(outputStream*, bool, bool, bool)+0x201
V  [libjvm.so+0x734927]  VM_PrintThreads::doit()+0x27
V  [libjvm.so+0x734576]  VM_Operation::evaluate()+0x46
V  [libjvm.so+0x733a23]  VMThread::evaluate_operation(VM_Operation*)+0x83
V  [libjvm.so+0x733c90]  VMThread::loop()+0x190
V  [libjvm.so+0x733780]  VMThread::run()+0x80
V  [libjvm.so+0x5e294e]  java_start(Thread*)+0x14e
C  [libpthread.so.0+0x54ab]  short+0x8b

VM_Operation (0x0caff000): PrintThreads, mode: safepoint, requested by thread 0x09ec3800


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

Java Threads: ( => current thread )
...//209 Java Threads

Heap
 par new generation   total 147456K, used 126550K [0x161f0000, 0x201f0000, 0x201f0000)
  eden space 131072K,  92% used [0x161f0000, 0x1d869d18, 0x1e1f0000)
  from space 16384K,  31% used [0x1e1f0000, 0x1e70be78, 0x1f1f0000)
  to   space 16384K,   0% used [0x1f1f0000, 0x1f1f0000, 0x201f0000)
 concurrent mark-sweep generation total 1884160K, used 1697819K [0x201f0000, 0x931f0000, 0x931f0000)
 concurrent-mark-sweep perm gen total 262144K, used 61769K [0x931f0000, 0xa31f0000, 0xb31f0000)

Code Cache  [0xb391f000, 0xb44b7000, 0xb691f000)
 total_blobs=3924 nmethods=3719 adapters=157 free_code_cache=38272704 largest_free_block=9600

print the memory size every minute, and found that the VmSize was 2924700 kB before the process died. 每分钟打印一次内存大小,发现VmSize在进程死亡之前是2924700 kB。

AFAIK On Linux the OS uses about 1 GB. AFAIK在Linux上,操作系统使用大约1 GB。 You need virtual memory for thread stacks, shared libraries, Perm Gen, memory mapped files, and any native resources. 您需要虚拟内存用于线程堆栈,共享库,Perm Gen,内存映射文件和任何本机资源。

If you are getting anywhere near this limit (or if you just have a 64-bit processor) you really should be using a 64-bit OS and JVM. 如果你接近这个限制(或者如果你只有一个64位处理器),你真的应该使用64位操作系统和JVM。 I would use Java 6 update 45, which is end of free support, if not Java 7 update 25. 我会使用Java 6更新45,这是免费支持的结束,如果不是Java 7更新25。

process size limit 流程大小限制

Modern Linux OSs can use more than 4GB of RAM when in the 32bit version by using something called Physical Address Extension (PAE) . 通过使用称为物理地址扩展(PAE)的东西,现代Linux操作系统在32位版本中可以使用超过4GB的RAM。

But if you don't do anything, 3GB seems like a reasonable limit that processes may hit. 但如果你不做任何事情,3GB似乎是一个合理的限制,进程可能会受到影响。

That said, this is completely unrelated to your case. 那就是说,这与你的情况完全无关。 The error is not from the kernel (you didn't get a core dump) but from the Java runtime. 错误不是来自内核(您没有获得核心转储),而是来自Java运行时。

The reason why it happens in the GC is that some other thread asked for another 83886088 bytes of free memory and there wasn't any left. 它在GC中发生的原因是一些其他线程要求另外83886088字节的空闲内存并且没有任何剩余。 So the VM started the GC to make room. 因此VM启动了GC以腾出空间。 Unfortunately, all objects were still in use -> out of memory error. 不幸的是,所有对象仍在使用 - >内存不足错误。

Why JVM allocate 83886088 bytes memory every time? 为什么JVM每次分配83886088字节的内存?

Software should be deterministic, that is it should produce the same results every time you run it. 软件应该是确定性的,即每次运行它时应该产生相同的结果。

Look at the other threads. 看看其他线程。 One of them just tried to allocate exactly this memory. 其中一个人试图准确分配这个记忆。

How many memory should be reserved for JVM besides heap memory(-Xmx) and non-heap memory(-XX:MaxPermSize)? 除了堆内存(-Xmx)和非堆内存(-XX:MaxPermSize)之外,应该为JVM保留多少内存?

That depends on what your application does. 这取决于您的应用程序的功能。 But usually, out of memory means you have a memory leak (ie something holds on to big objects that it doesn't really need anymore). 但通常情况下,内存不足意味着你有内存泄漏(即大型对象上存在的东西,它实际上并不需要它)。

Use a profiler like MAT or YourKit to determine what that could be. 使用MATYourKit等分析器来确定可能的内容。

And how to know how many it's using now? 如何知道它现在使用了多少?

Use jconsole or VisualVM to monitor the memory usage. 使用jconsoleVisualVM监视内存使用情况。

Related: 有关:

Try to change the stack size for a thread, use the -Xss=N flag (eg, - Xss=256k ). 尝试更改线程的堆栈大小,使用-Xss = N标志(例如, - Xss = 256k )。 By default for linux the size is 320 KB (In 64 bit machine the size is 1 MB). 默认情况下,linux的大小为320 KB (在64位计算机中,大小为1 MB)。 Generally, Out of Native Memory happens because of following reasons: 通常,Out of Native Memory由于以下原因而发生:

Please note that changing the stack size will help in case of 1 and 2. 请注意,更改堆栈大小将有助于1和2的情况。

  1. In a 32-bit JVM, the process is at its 4 GB (or less, depending on the OS) maximum size. 在32位JVM中,该进程的最大大小为4 GB(或更低,取决于操作系统)。
  2. The system has actually run out of virtual memory. 系统实际上耗尽了虚拟内存。
  3. On Unix-style systems, the user has already created (between all programs she is running) the maximum number of processes configured for her login. 在Unix风格的系统上,用户已经(在她正在运行的所有程序之间)创建了为其登录配置的最大进程数。 Individual threads are considered a process in that regard. 在这方面,单个线程被认为是一个过程。

Hope this helps. 希望这可以帮助。

Regards, Pinaki 此致,Pinaki

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM