2013-04-20 63 views
-8

我有一个服务器,通过套接字处理请求,并产生一个线程来处理每个请求。为什么我会得到java.lang.OutOfMemory错误?

为什么我得到java.lang.OutOfMemoryError,我该怎么办才能修复它?

+3

也许是在33-40行,你创建一个大小为2 ** 29的字节数组,并把它添加到一个ArrayList 无限循环。 – 2013-04-20 02:43:38

+0

https://www.google.co.in/search?q=reasons+for+java+outofmemoryexception+&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a – Jayan 2013-04-20 02:45:13

+1

请确保如果你回答自己的问题,这个问题是适合独立的。原来,这个问题属于“不是真正的问题”。 – Zyerah 2013-04-20 02:49:32

回答

2

类型I:超出堆空间。

这是最常见的错误。追查可能很难,因为它涉及了解什么物体是“正常”的,哪些物体应该被释放。

创建无限量的引用对象。创建特定于线程的对象,但会被另一个全局对象引用。

如果你能重现该问题,运行jmap -dump:format=b,file=output.bin

然后分析了堆文件,jhat

II型:进程的内存

的。如果你已经实现了JNI调用,或对代表您的JVM,这 创建JNI对象创建的对象,你可以运行进程的内存,这对于32位进程是4演出。

正在运行的Java进程的进程空间包括:

  • JVM内存
  • 加载库
  • 本地创建的对象

-Xmx只能控制JVM的大小记忆。

III型:垃圾收集不运行

我还没有发现这种情况在任何网络搜索的任何引用。我想我已阅读每个帖子来解决​​。

如果您有一个Java程序正在对本地代码进行JNI调用,那么当任何线程处于JNI调用时,垃圾收集器不会运行。给定一个足够繁忙的系统,在JNI调用中有两个或多个线程,这可能导致垃圾收集器无法运行。

第一个实例是一个长时间运行的JNI调用,它将回调到java代码中以释放当前对象并获取新对象。在每次迭代中,使用的内存量增加,未使用的对象不会被垃圾收集。

第二个实例是一个测试,其中每个派生线程都会导致JNI调用。该代码会运行很长时间,大约一个小时左右,但会死亡java.lang.OutOfMemoryError-Xloggc选项在前4000秒内显示定期垃圾回收,直到正在运行的并发线程数增加为止。

4055.330: [GC 4055.330: [ParNew: 147424K->12220K(147456K), 0.0073372 secs] 769563K->637289K(1294336K) icms_dc=0 , 0.0073809 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
18668.710: [GC 18668.710: [ParNew: 143289K->16384K(147456K), 0.0297121 secs] 768358K->651851K(1294336K) icms_dc=0 , 0.0297604 secs] 

[更新2014年6月7日] 在一种情况下,我发现这个答案Memory leak when calling java code from C using JNI固定的问题。 本地java内存被分配给C栈,即使它是在java中分配的,因为它是在JNI调用中完成的。具体来说,我使用PushLocalFrame()/ PopLocalFrame()将回调函数包装为java来解决问题。