Chinaunix首页 | 论坛 | 博客
  • 博客访问: 258992
  • 博文数量: 70
  • 博客积分: 2500
  • 博客等级: 少校
  • 技术积分: 930
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-22 12:32
文章存档

2009年(42)

2008年(28)

我的朋友

分类:

2009-04-08 09:40:41

:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://itsxhu.blogbus.com/logs/21994494.html

OutOfMemory问题解决方法

前段时间负责的系统出现多次OutOfMemory问题,在解决这个问题总看过了非常多的文档,对于这个问题的解决也有了一点自己的认识。今天将其总结一下,希望对其它碰到相同问题的朋友能有一些启示。
   系统出来OufOfMemory问题的原因有很多种,首先需要根据出现OutOfMemory时打印的日志来分析出现这个的原因,然后根据分析结果选择对应的策略。在分析日志之前需要对JVM内存管理有一个比较深刻的认识,这样才能明白到底是哪个地方出了问题。下面是摘自Memory Management white paper(这份文档在SUN官方网站有下载,值得一看)的一段描述:
 •Java heap space
    This indicates that an object could not be allocated in the heap. The issue may be just a configuration
    problem. You could get this error, for example, if the maximum heap size specified by the –Xmx
    command line option (or selected by default) is insufficient for the application. It could also be an
    indication that objects that are no longer needed cannot be garbage collected because the
    application is unintentionally holding references to them. The HAT tool (see Section 7) can be used to
    view all reachable objects and understand which references are keeping each one alive. One other
    potential source of this error could be the excessive use of finalizers by the application such that the
    thread to invoke the finalizers cannot keep up with the rate of addition of finalizers to the queue. The
    jconsole management tool can be used to monitor the number of objects that are pending
    finalization.
• PermGen space
  This indicates that the permanent generation is full. As described earlier, that is the area of the heap
  where the JVM stores its metadata. If an application loads a large number of classes, then the
  permanent generation may need to be increased. You can do so by specifying the command line
  option –XX:MaxPermSize=n, where n specifies the size.
• Requested array size exc-Xloggc: eeds VM limit
  This indicates that the application attempted to allocate an array that is larger than the heap size. For
  example, if an application tries to allocate an array of 512MB but the maximum heap size is 256MB,
  then this error will be thrown. In most cases the problem is likely to be either that the heap size is too
  small or that a bug results in the application attempting to create an array whose size is calculated to
  be incorrectly huge.

    一般出现比较多的是Heap空间不足导致OutOfMemory,这时的报错提示是java.lang.OutOfMemoryError: Java heap space,这种情况下只需要在程序启动时调整一下内存就行,调整的方式是用-Xms -Xmx参数。这个可能参照Eclipse启动时的那一串参数,不过我指的是在Windows下面,Linux下面还没找到这个启动的参数。
   另外一种情况是出现java.lang.OutOfMemoryError: PermGen space的异常。这种异常的原因是PermGen区内存不足,需要解决这个问题你就需要对JVM里面对内存的管理比较熟悉了。在JVM中这个PermGen区是存放所有装载了到系统中的class,interface的meta data的。这时用–XX:MaxPermSize=n来改变PermGen的大小,找到一个适当的大小就能解决这个问题了。
   第三种情况是申请的内存空间的大小走过了JVM所能提供的大小,或者是申请一块大内存区域分配内存时没有连续的内存,导致出现OutOfMemory。这种情况不是内存不够的问题,而是内存区中出现太多内存碎片导致无法分配大块内存,这时候需要GC来工作了。 关于GC的工作原理,以及每一种GC算法的策略可能参见相关JVM的文档,根据这个文档提供的策略进行的GC调优。 GC调优是一个非常大的概念,不同的情况采用的策略大不相同,需要针对系统进行大量的分析。
   GC调优的一些基本做法是先将GC的日志打印出来进行分析,首先确认是否是代码层存在内存泄漏问题。通过在启动时设置-Xloggc: 参数,将日志保存到file这个文件中,然后通过一些专门查看这咱日志的工具对文件进行分析,确认问题的原因。 这通常也是JVM性能优化的一个步骤。具体的GC调优方法在Memory Management white paper中也有大量的介绍。这个问题在这篇文章中就详细讲述了。
   还有一些情况的OufOfMemory非常奇怪,出现这类情况时打印的日志只有OutOfMemoryError: unable to create new native thread这个异常。这种情况是最麻烦的,需要解决这个问题需要对JVM规范中关于java thread有所了解。 在JVM中每创建一个线程时都会在OS级创建相应的对应线程,但是不一定是1:1的关系,这个涉及到JVM的thread model的问题,目前找到的资源料中显示在Solaris sparc中存在N:M和1:1模型可选择。回到正题,当JVM中在分配线程时发现OS中已经没有足够的线程来创建其相应的OS级对应线程就可能会出现这种问题。这时解决的方法是减小JVM中申请创建的线程数,让OS拥有更多的内存来创建新的线程,在前面一篇文章就有提到的heap的内存不能超过物理内存的1/4。

如果采用了所有以上策略还是没有找到解决方法的朋友,那么恭喜你,你可能发现了JVM的一个Bug。给Sun或者相应的JVM开发商报告并寻求解决方案吧。

   最后再一次建议遇到这种问题的朋友请认真阅读一下SUN官方给出的Memory Management in the Java HotSpot Virtual Machine,其下载地址如下:java.sun.com/j2se/reference/whitepapers/memorymanagement_whitepaper.pdf

阅读(1363) | 评论(0) | 转发(0) |
0

上一篇:java中时间处理

下一篇:JVM Specification(2)

给主人留下些什么吧!~~