【java】OOM

来源:互联网 发布:java开源 编辑:程序博客网 时间:2024/05/16 16:01



官网:

https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/memleaks002.html


1.    Exception in thread thread_name: java.lang.OutOfMemoryError: Java heap space

堆没有足够的内存空间---可能是内存泄露

也可能是过度使用了finalize,即已经被回收了 结果又去回收一遍
Cause: The detail message Java heap space indicates object could not be allocated in the Java heap. This error does not necessarily imply a memory leak. The problem can be as simple as a configuration issue, where the specified heap size (or the default size, if it is not specified) is insufficient for the application.
In other cases, and in particular for a long-lived application, the message might be an indication that the application is unintentionally holding references to objects, and this prevents the objects from being garbage collected. This is the Java language equivalent of a memory leak. Note: The APIs that are called by an application could also be unintentionally holding object references.

One other potential source of this error arises with applications that make excessive use of finalizers. If a class has a finalize method, then objects of that type do not have their space reclaimed at garbage collection time. Instead, after garbage collection, the objects are queued for finalization, which occurs at a later time. In the Oracle Sun implementation, finalizers are executed by a daemon thread that services the finalization queue. If the finalizer thread cannot keep up, with the finalization queue, then the Java heap could fill up and this type of OutOfMemoryError exception would be thrown. One scenario that can cause this situation is when an application creates high-priority threads that cause the finalization queue to increase at a rate that is faster than the rate at which the finalizer thread is servicing that queue.


Action: You can find more information about how to monitor objects for which finalization is pending in Monitor the Objects Pending Finalization.


2.  Exception in thread thread_name: java.lang.OutOfMemoryError: GC Overhead limit exceeded

回收一点时间结果花费了大量时间
Cause: The detail message "GC overhead limit exceeded" indicates that the garbage collector is running all the time and Java program is making very slow progress. After a garbage collection, if the Java process is spending more than approximately 98% of its time doing garbage collection and if it is recovering less than 2% of the heap and has been doing so far the last 5 (compile time constant) consecutive garbage collections, then a java.lang.OutOfMemoryError is thrown. This exception is typically thrown because the amount of live data barely fits into the Java heap having little free space for new allocations.
Action: Increase the heap size. The java.lang.OutOfMemoryError exception for GC Overhead limit exceeded can be turned off with the command line flag -XX:-UseGCOverheadLimit.

3.  Exception in thread thread_name: java.lang.OutOfMemoryError: Requested array size exceeds VM limit

申请的数组超出了虚拟机的限制
Cause: The detail message "Requested array size exceeds VM limit" indicates that the application (or APIs used by that application) attempted to allocate an array that is larger than the heap size. For example, if an application attempts to allocate an array of 512 MB but the maximum heap size is 256 MB then OutOfMemoryError will be thrown with the reason Requested array size exceeds VM limit.
Action: Usually the problem is either a configuration issue (heap size too small), or a bug that results in an application attempting to create a huge array (for example, when the number of elements in the array is computed using an algorithm that computes an incorrect size).


4.Exception in thread thread_name: java.lang.OutOfMemoryError: Metaspace

在1.8之前被称之为有永久区,现在是Metaspace区,主体还是指空间放满了,可以适当增大Metasapce。
Cause: Java class metadata (the virtual machines internal presentation of Java class) is allocated in native memory (referred to here as metaspace). If metaspace for class metadata is exhausted, a java.lang.OutOfMemoryError exception with a detail MetaSpace is thrown. The amount of metaspace that can be used for class metadata is limited by the parameter MaxMetaSpaceSize, which is specified on the command line. When the amount of native memory needed for a class metadata exceeds MaxMetaSpaceSize, a java.lang.OutOfMemoryError exception with a detail MetaSpace is thrown.
Action: If MaxMetaSpaceSize, has been set on the command-line, increase its value. MetaSpace is allocated from the same address spaces as the Java heap. Reducing the size of the Java heap will make more space available for MetaSpace. This is only a correct trade-off if there is an excess of free space in the Java heap. See the following action for Out of swap space detailed message.


5.Exception in thread thread_name: java.lang.OutOfMemoryError: request size bytes for reason. Out of swap space?
Cause: The detail message "request size bytes for reason. Out of swap space?" appears to be an OutOfMemoryError exception. However, the Java HotSpot VM code reports this apparent exception when an allocation from the native heap failed and the native heap might be close to exhaustion. The message indicates the size (in bytes) of the request that failed and the reason for the memory request. Usually the reason is the name of the source module reporting the allocation failure, although sometimes it is the actual reason.
Action: When this error message is thrown, the VM invokes the fatal error handling mechanism (that is, it generates a fatal error log file, which contains useful information about the thread, process, and system at the time of the crash). In the case of native heap exhaustion, the heap memory and memory map information in the log can be useful. For more information about understanding the fatal error log file, see Appendix A.
If this type of the OutOfMemoryError exception is thrown, you might need to use troubleshooting utilities on the operating system to diagnose the issue further. For more information about tools available for various operating systems, see Native Operating System Tools.


6 Exception in thread thread_name: java.lang.OutOfMemoryError: Compressed class space
Cause: On 64-bit platforms a pointer to class metadata can be represented by a 32-bit offset (with UseCompressedOops). This is controlled by the command line flag UseCompressedClassPointers (on by default). If the UseCompressedClassPointers is used, the amount of space available for class metadata is fixed at the amount CompressedClassSpaceSize. If the space needed for UseCompressedClassPointers exceeds CompressedClassSpaceSize, a java.lang.OutOfMemoryError with detail Compressed class space is thrown.
Action: Increase CompressedClassSpaceSize to turn off UseCompressedClassPointers. Note: There are bounds on the acceptable size of CompressedClassSpaceSize. For example -XX: CompressedClassSpaceSize=4g, exceeds acceptable bounds will result in a message such as
CompressedClassSpaceSize of 4294967296 is invalid; must be between 1048576 and 3221225472.


Note: There is more than one kind of class metadata - klass metadata and other metadata. Only klass metadata is stored in the space bounded by CompressedClassSpaceSize. The other metadata is stored in Metaspace.


7.Exception in thread thread_name: java.lang.OutOfMemoryError: reason stack_trace_with_native_method
Cause: If the detail part of the error message is "reason stack_trace_with_native_method" and a stack trace is printed in which the top frame is a native method, then this is an indication that a native method has encountered an allocation failure. The difference between this and the previous message is that the allocation failure was detected in a Java Native Interface (JNI) or native method rather than in the JVM code.
Action: If this type of the OutOfMemoryError exception is thrown, you might need to use native utilities of the OS to further diagnose the issue. For more information about tools available for various operating systems, see Native Operating System Tools.


1、OutOfMemory的四种情况
 
1) 永久区溢出    Exception in thread "main" java.lang.OutOfMemoryError: PermGen space  
           
         这一部分用于存放Class和Meta的信息,Class在被 Load的时候被放入PermGen space区域(包括常量池: 静态变量),它和存放Instance的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误。
         这种错误常见在web服务器对JSP进行pre compile的时候。
         可以通过设置jvm启动参数来解决: -XX:MaxPermSize=256m

package OOM;import java.util.ArrayList;import java.util.List;/** * -XX:+HeapDumpOnOutOfMemoryError -XX:MaxPermSize=2m */public class PermGenSpace {    public static void main(String[] args) {        List<String> list = new ArrayList<>();        int i=0;        while(true){            list.add(String.valueOf(i++).intern());  //public native String intern();        }    }}

2)堆溢出  java.lang.OutOfMemoryError: Java heap space
 
          这部分用于存放类的实例。被缓存的实例(Cache)对象,大的map,list引用大的对象等等,都会保存于此。
          堆内存会在jvm启动时自动设置,初始值 -Xms为物理内存的1/64,最大值-Xmx为1/4;可以通过参数-Xmn、-Xms、-Xmx设置,一般-Xms和-Xmx不超过80%,-Xmn为-Xmx的1/4;

package OOM;import java.util.ArrayList;import java.util.List;/** * -XX:+HeapDumpOnOutOfMemoryError -Xms20m -Xmx20m  -XX:MaxNewSize=10m */public class HeapSpace {    public static void main(String[] args) {        List<String> list = new ArrayList<>();        int i=0;        while(true){            list.add(new String(""+i++));        }    }}

3)java.lang.OutOfMemoryError: GC overhead limit exceeded
      JDK6新增错误类型。当GC为释放很小空间占用大量时间时抛出。
 
可以添加JVM的启动参数来限制使用内存:-XX:-UseGCOverheadLimit
 
4)栈溢出错误,非规范的OutOfMemoryError     Exception in thread "main" java.lang.StackOverflowError
 
          这部分用于存放局部变量、方法栈帧信息。栈帧太多,也就是函数调用层级过多时就会出现此异常,检查是否有死递归的情况。 
           对应的启动参数为:-Xss ( JDK1.5以后默认是1M,之前是256K)
 
package OOM;/** * -XX:+HeapDumpOnOutOfMemoryError -Xss(默认1M) */public class StackOverflow {    public int i=0;    public void stackLeak(){        i++;        stackLeak();    }    public static void main(String[] args) {        StackOverflow sof = new StackOverflow();        sof.stackLeak();    }}

  实例,以下是1G内存环境下java jvm 的参数设置参考: 
               JAVA_OPTS="-server -Xms800m -Xmx800m -XX:PermSize=64M -XX:MaxNewSize=256m -XX:MaxPermSize=128m -Djava.awt.headless=true 
 
2、dump排查方案
        jvm启动时添加参数-XX:+HeapDumpOnOutOfMemoryError,这样当内存溢出时,会生成dump文件:
 
          java.lang.OutOfMemoryError: Java heap space 
          Dumping heap to java_pid5304.hprof ... 
          Heap dump file created [85357895 bytes in 2.095 secs]
 
       使用Memory Analyze分析,查看类使用情况;
 
3、分析工具
1)动态分析,实时 :  Jprofile
2)静态分析 ,需要dump文件:     Eclipse Memory Analyzer等


参考资料:

http://wade6.iteye.com/blog/1978147

http://www.cnblogs.com/zhuwenjoyce/p/6536846.html

http://blog.csdn.net/u011080472/article/details/51322119

0 0
原创粉丝点击