首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Java内存不足(本机内存),进程大小限制被击中(32位linux)

Java内存不足(本机内存),进程大小限制被击中(32位linux)
EN

Stack Overflow用户
提问于 2013-09-05 07:58:52
回答 3查看 19.5K关注 0票数 4

我正在测试一个web应用程序的性能,并得到了“内存错误”(本机内存)。

我进行了几次测试,每次它“未能为块::new”分配83886088字节时就死掉了。

我每分钟打印一次内存大小,发现进程死前的VmSize是2924700 kB。

我认为进程大小限制被击中了。我把-Xmx2000m改为-Xmx1900m,现在可以了。

一些问题:

1.如何确定达到了工艺尺寸限制。它不完全是3G内存。

2.为什么JVM每次分配83886088字节内存?从异常堆栈来看,它似乎与GC相关。

3.除了堆内存(-Xmx)和非堆内存(-XX:MaxPermSize)之外,应该为JVM保留多少内存?怎么知道现在用了多少?

谢谢,为我糟糕的英语感到难过。

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

代码语言:javascript
运行
复制
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
EN

回答 3

Stack Overflow用户

发布于 2013-09-05 08:03:55

每分钟打印一次内存大小,发现进程死前VmSize为2924700 kB。

在Linux上,操作系统使用大约1GB的AFAIK。您需要用于线程堆栈、共享库、Perm、内存映射文件和任何本机资源的虚拟内存。

如果你正在接近这个限制(或者你只有一个64位处理器),你真的应该使用64位操作系统和JVM。如果不是Java 7更新25,我会使用Java 6 update 45,这是免费支持的结束。

票数 3
EN

Stack Overflow用户

发布于 2013-09-05 08:15:22

工艺尺寸限制

在32位版本中,现代Linux可以使用超过4GB的内存,这是通过使用物理地址扩展(PAE)来实现的。

但是,如果您不做任何事情,3GB似乎是一个合理的限制,进程可能会达到。

这和你的案子完全无关。错误不是来自内核(没有得到核心转储),而是来自Java运行时。

在GC中发生这种情况的原因是,其他线程请求另外83886088字节的空闲内存,而没有剩下任何内存。所以VM启动了GC以腾出空间。不幸的是,所有对象仍然在使用->内存错误。

为什么JVM每次分配83886088字节内存?

软件应该是确定性的,也就是说,它应该在每次运行它时产生相同的结果。

看看其他的线。其中一人只是试图分配这个内存。

除了堆内存(-Xmx)和非堆内存(-XX:MaxPermSize)之外,应该为JVM保留多少内存?

这取决于应用程序的功能。但是,通常情况下,内存不足意味着内存泄漏(即,一些不需要的大对象)。

使用像垫子YourKit这样的分析器来确定可能是什么。

怎么知道现在用了多少?

使用J控制台VisualVM来监视内存使用情况。

相关信息:

  • http://memoryanalyzer.blogspot.co.uk/,特别是http://memoryanalyzer.blogspot.co.uk/2008/05/automated-heap-dump-analysis-finding.html
  • http://www.oracle.com/technetwork/java/javase/memleaks-137499.html
  • Oracle:内存泄漏的故障排除
票数 1
EN

Stack Overflow用户

发布于 2015-06-15 15:33:53

尝试更改线程的堆栈大小,使用-Xss=N标志(例如,-Xss=256k)。默认情况下,linux的大小为320 KB(在64位机器中大小为1MB)。通常,本机内存不足的原因如下:

请注意,在1和2.的情况下,更改堆栈大小会有所帮助。

  1. 在32位JVM中,进程的最大大小为4GB(或更小,取决于操作系统)。
  2. 这个系统实际上已经耗尽了虚拟内存。
  3. 在Unix风格的系统上,用户已经创建了(在她正在运行的所有程序之间)为她的登录配置的最大进程数。在这方面,单个线程被认为是一个进程。

希望这能有所帮助。

你好,皮纳基

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18630790

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档