What to Do about OutOfMemoryError
One common issue that many developers have to address is that of applications that terminate with java.lang.OutOfMemoryError. That error is thrown when there is insufficient space to allocate an object. That is, garbage collection cannot make any further space available to accommodate a new object, and the heap cannot be further expanded. An OutOfMemoryError does not necessarily imply a memory leak. The issue might simply be a configuration issue, for example if the specified heap size (or the default size if not specified) is insufficient for the application.
The first step in diagnosing an OutOfMemoryError is to examine the full error message. In the exception message, further information is supplied after “java.lang.OutOfMemoryError”. Here are some common examples of what that additional information may be, what it may mean, and what to do about it:
• 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 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 exceeds 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.
HotSpot Generations
Memory in the Java HotSpot virtual machine is organized into three generations: a young generation , an old generation(Tenured Gen ), and a permanent generation . Most objects are initially allocated in the young generation. The old generation contains objects that have survived some number of young generation collections, as well as some large objects that may be allocated directly in the old generation. The permanent generation holds objects that the JVM finds convenient to have the garbage collector manage, such as objects describing classes and methods,as well as the classes and methods themselves.
The young generation consists of an area called Eden plus two smaller survivor spaces.
Most objects are initially allocated in Eden. (As mentioned, a few large objects may be allocated directly in the old generation.) The survivor spaces hold objects that have survived at least one young generation collection and have thus been given additional chances to die before being considered “old enough” to be promoted to the old generation. At any given time, one of the survivor spaces (labeled From in the figure) holds such objects, while the other is empty and remains unused until the next collection.
Runtime Data Areas
The Java virtual machine defines various runtime data areas that are used during execution of a program. Some of these data areas are created on Java virtual machine start-up and are destroyed only when the Java virtual machine exits. Other data areas are per thread. Per-thread data areas are created when a thread is created and destroyed when the thread exits.
1. The pc Register
The Java virtual machine can support many threads of execution at once . Each Java virtual machine thread has its own pc (program counter) register . At any point, each Java virtual machine thread is executing the code of a single method, the current method for that thread. If that method is not native , the pc register contains the address of the Java virtual machine instruction currently being executed . If the method currently being executed by the thread is native , the value of the Java virtual machine's pc register is undefined. The Java virtual machine's pc register is wide enough to hold a returnAddress or a native pointer on the specific platform.
2. Java Virtual Machine Stacks
Each Java virtual machine thread has a private Java virtual machine stack , created at the same time as the thread. A Java virtual machine stack stores frames (§3.6) . A Java virtual machine stack is analogous to the stack of a conventional language such as C: it holds local variables and partial results, and plays a part in method invocation and return . Because the Java virtual machine stack is never manipulated directly except to push and pop frames, frames may be heap allocated. The memory for a Java virtual machine stack does not need to be contiguous.
The Java virtual machine specification permits Java virtual machine stacks either to be of a fixed size or to dynamically expand and contract as required by the computation. If the Java virtual machine stacks are of a fixed size, the size of each Java virtual machine stack may be chosen independently when that stack is created. A Java virtual machine implementation may provide the programmer or the user control over the initial size of Java virtual machine stacks, as well as, in the case of dynamically expanding or contracting Java virtual machine stacks, control over the maximum and minimum sizes.
The following exceptional conditions are associated with Java virtual machine stacks:
If the computation in a thread requires a larger Java virtual machine stack than is permitted, the Java virtual machine throws a StackOverflowError.
If Java virtual machine stacks can be dynamically expanded, and expansion is attempted but insufficient memory can be made available to effect the expansion, or if insufficient memory can be made available to create the initial Java virtual machine stack for a new thread, the Java virtual machine throws an OutOfMemoryError.
3. Heap
The Java virtual machine has a heap that is shared among all Java virtual machine threads. The heap is the runtime data area from which memory for all class instances and arrays is allocated.
The heap is created on virtual machine start-up . Heap storage for objects is reclaimed by an automatic storage management system (known as a garbage collector ) ; objects are never explicitly deallocated. The Java virtual machine assumes no particular type of automatic storage management system, and the storage management technique may be chosen according to the implementor's system requirements. The heap may be of a fixed size or may be expanded as required by the computation and may be contracted if a larger heap becomes unnecessary. The memory for the heap does not need to be contiguous.
A Java virtual machine implementation may provide the programmer or the user control over the initial size of the heap, as well as, if the heap can be dynamically expanded or contracted, control over the maximum and minimum heap size.
The following exceptional condition is associated with the heap:
If a computation requires more heap than can be made available by the automatic storage management system, the Java virtual machine throws an OutOfMemoryError.
4. Method Area
The Java virtual machine has a method area that is shared among all Java virtual machine threads. The method area is analogous to the storage area for compiled code of a conventional language or analogous to the "text" segment in a UNIX process. It stores per-class structures such as the runtime constant pool, field and method data, and the code for methods and constructors, including the special methods(§3.9) used in class and instance initialization and interface type initialization.
The method area is created on virtual machine start-up . Although the method area is logically part of the heap , simple implementations may choose not to either garbage collect or compact it. This version of the Java virtual machine specification does not mandate the location of the method area or the policies used to manage compiled code. The method area may be of a fixed size or may be expanded as required by the computation and may be contracted if a larger method area becomes unnecessary. The memory for the method area does not need to be contiguous.
A Java virtual machine implementation may provide the programmer or the user control over the initial size of the method area, as well as, in the case of a varying-size method area, control over the maximum and minimum method area size.
The following exceptional condition is associated with the method area:
If memory in the method area cannot be made available to satisfy an allocation request, the Java virtual machine throws an OutOfMemoryError.
5. Runtime Constant Pool
A runtime constant pool is a per-class or per-interface runtime representation of the constant_pool table in a class file . It contains several kinds of constants, ranging from numeric literals known at compile time to method and field references that must be resolved at run time. The runtime constant pool serves a function similar to that of a symbol table for a conventional programming language, although it contains a wider range of data than a typical symbol table.
Each runtime constant pool is allocated from the Java virtual machine's method area . The runtime constant pool for a class or interface is constructed when the class or interface is created by the Java virtual machine.
The following exceptional condition is associated with the construction of the runtime constant pool for a class or interface:
When creating a class or interface, if the construction of the runtime constant pool requires more memory than can be made available in the method area of the Java virtual machine, the Java virtual machine throws an OutOfMemoryError .
6. Native Method Stacks
An implementation of the Java virtual machine may use conventional stacks, colloquially called "C stacks," to support native methods, methods written in a language other than the Java programming language. Native method stacks may also be used by the implementation of an interpreter for the Java virtual machine's instruction set in a language such as C. Java virtual machine implementations that cannot load native methods and that do not themselves rely on conventional stacks need not supply native method stacks. If supplied, native method stacks are typically allocated per thread when each thread is created.
The Java virtual machine specification permits native method stacks either to be of a fixed size or to dynamically expand and contract as required by the computation. If the native method stacks are of a fixed size, the size of each native method stack may be chosen independently when that stack is created. In any case, a Java virtual machine implementation may provide the programmer or the user control over the initial size of the native method stacks. In the case of varying-size native method stacks, it may also make available control over the maximum and minimum method stack sizes.
The following exceptional conditions are associated with native method stacks:
If the computation in a thread requires a larger native method stack than is permitted, the Java virtual machine throws a StackOverflowError .
If native method stacks can be dynamically expanded and native method stack expansion is attempted but insufficient memory can be made available, or if insufficient memory can be made available to create the initial native method stack for a new thread, the Java virtual machine throws an OutOfMemoryError .
-Xms n
initial heap size
-Xmx n
maximum heap size
On machines that are not server-class machines, the default values for JVM, garbage collector, and heap sizes are
• the client JVM
• the serial garbage collector
• Initial heap size of 4MB
• Maximum heap size of 64MB
On a server-class machine, the JVM is always the server JVM unless you explicitly specify the -client command line option to request the client JVM. On a server-class machine running the server JVM, the default garbage collector is the parallel collector. Otherwise, the default is the serial collector.
On a server-class machine running either JVM (client or server) with the parallel garbage collector, the default initial and maximum heap sizes are
• Initial heap size of 1/64th of the physical memory, up to 1GB. (Note that the minimum initial heap size is 32MB, since a server-class machine is defined to have at least 2GB of memory and 1/64th of 2GB is 32MB.)
• Maximum heap size of 1/4th of the physical memory, up to 1GB.
-Xss n
Set thread stack size.
-XX:MaxPermSize =n
Maximum size of the permanent generation.
-XX:+UseSerialGC serial garbage collector (for smaller applications and systems)
-XX:+UseParallelGC parallel (throughput) garbage collector
-XX:+UseParallelOldGC Parallel compacting
-XX:+UseConcMarkSweepGC concurrent (low pause time) garbage collector (also known as CMS)
It is a parallel and mostly-concurrent collector and and can be a good match for the threading ability of an large multi-processor systems.
–XX:NewSize=n
Default initial size of the new (young) generation,in bytes.
–XX:NewRatio=n
Ratio between the young and old generations. For example, if n is 3, then the ratio is 1:3 and the combined size of Eden and the survivor spaces is one fourth of the total size of the young and old generations.
Generally speaking the largest recommended value for the young generation is 3/8 of the maximum heap size.
-XX:ParallelGCThreads =n
Reduces the number of garbage collection threads. The default would be equal to the processor count, which would probably be unnecessarily high on a 32 thread capable system.
-XX:SurvivorRatio =n
Ratio between each survivor space and Eden. Forexample, if n is 7, each survivor space is one–ninth of the young generation (not one–eighth, because there are two survivor spaces). Larger survivor spaces allow short lived objects a longer time period to die in the young generation.
-XX:MaxTenuringThreshold =31
Allows short lived objects a longer time period to die in the young generation (and hence, avoid promotion). A consequence of this setting is that minor GC times can increase due to additional objects to copy. This value and survivor space sizes may need to be adjusted so as to balance overheads of copying between survivor spaces versus tenuring objects that are going to live for a long time. The default settings for CMS are SurvivorRatio=1024 and MaxTenuringThreshold=0 which cause all survivors of a scavenge to be promoted. This can place a lot of pressure on the single concurrent thread collecting the tenured generation. Note: when used with -XX:+UseBiasedLocking, this setting should be 15.
-XX:+UseBiasedLocking
Enables a technique for improving the performance of uncontended synchronization. An object is "biased" toward the thread which first acquires its monitor via a monitorenter bytecode or synchronized method invocation; subsequent monitor-related operations performed by that thread are relatively much faster on multiprocessor machines. Some applications with significant amounts of uncontended synchronization may attain significant speedups with this flag enabled; some applications with certain patterns of locking may see slowdowns, though attempts have been made to minimize the negative impact.
-XX:+AggressiveOpts
Turns on point performance optimizations that are expected to be on by default in upcoming releases. The changes grouped by this flag are minor changes to JVM runtime compiled code and not distinct performance features (such as BiasedLocking and ParallelOldGC). This is a good flag to try the JVM engineering team's latest performance tweaks for upcoming releases. Note: this option is experimental! The specific optimizations enabled by this option can change from release to release and even build to build. You should reevaluate the effects of this option with prior to deploying a new release of Java.
-XX:+HeapDumpOnOutOfMemoryError
Dump heap to file when java.lang.OutOfMemoryError is thrown
-XX:HeapDumpPath=
Path to directory or filename for heap dump
参考文档
Memory Management in the Java HotSpot Virtual Machine
The Java® Virtual Machine Specification
How to solve java.lang.OutOfMemoryError: unable to create new native thread
相关推荐
### Java 错误处理:java.lang.OutOfMemoryError: Java heap space 在Java应用程序开发过程中,经常遇到的一个问题就是内存溢出错误,特别是在处理大量数据或长时间运行的应用时。其中,“java.lang....
5. 无法创建新的原生线程(Unable to create new native thread) 当JVM尝试创建新的线程时,如果无法获取足够的原生内存来分配新线程的栈空间,就会抛出该错误。通常发生在系统限制了线程数量或是原生内存不足时。 ...
《junrar的OutOfMemoryError错误解决深度解析》 在日常的IT工作中,我们经常会遇到各种类型的问题,其中,`OutOfMemoryError`是一个常见的Java运行时异常,它表明程序在执行过程中耗尽了可用的内存资源。对于使用...
java.lang.OutOfMemoryError处理错误 java.lang.OutOfMemoryError是Java虚拟机(JVM)中的一种常见错误,发生这种错误时,JVM将无法继续运行,程序将崩溃。这种错误的出现通常是由于Jvm的内存不足或内存泄露导致的...
"Java.lang.OutOfMemoryError: Java heap space 解决方法" Java.lang.OutOfMemoryError: Java heap space 是 Java 中的一个常见错误,它发生时,Java 虚拟机 (JVM) 无法分配对象,因为堆空间不足。下面是解决该问题...
在使用Apache Ant构建Java项目时,可能会遇到一个常见的问题,即`OutOfMemoryError`。这个错误通常发生在编译大量Java源文件时,由于资源耗尽,JVM无法分配足够的内存来执行任务。`OutOfMemoryError`是Java运行时...
### 编译时出现java.lang.OutOfMemoryError Java heap space异常 #### 一、问题概述 在进行Java项目编译的过程中,可能会遇到`java.lang.OutOfMemoryError: Java heap space`这种异常。这类异常通常表明Java虚拟机...
java.lang.OutOfMemoryError: PermGen space 解决方案
在IT领域,尤其是在Java开发中,`OutOfMemoryError`是一个常见的问题,通常表明程序在运行过程中耗尽了分配给它的内存资源。这个问题在本案例中发生在网店系统的升级后,经过压力测试,系统突然崩溃,抛出了`...
### 解决OutOfMemoryError内存溢出 在Java开发过程中,我们经常会遇到`java.lang.OutOfMemoryError`(简称OOM)的问题。这个问题的发生主要是由于JVM内存不足或程序中存在内存泄漏所引起的。本文将深入探讨OOM产生...
### 解决OutOfMemoryError: PermGen space 在Java应用程序运行过程中,可能会遇到“OutOfMemoryError: PermGen space”的错误提示。这种错误通常发生在永久代(PermGen space)内存不足的情况下,永久代主要用于...
Java中的`java.lang.OutOfMemoryError`是一种常见的运行时错误,通常表示应用程序在尝试分配内存时遇到了问题。根据提供的信息,这个错误主要涉及到两个方面:`PermGen space`和`Java heap`,并且与Tomcat服务器相关...
### Myeclipse下java.lang.OutOfMemoryError: Java heap space的解决方案 在使用Myeclipse进行Java开发时,可能会遇到`java.lang.OutOfMemoryError: Java heap space`这个错误提示。这种异常通常发生在应用程序占用...
### Tomcat 出现 OutOfMemoryError 的解决方法 #### 一、问题概述 在部署应用至 Tomcat 服务器时,经常会遇到一个常见的错误:`java.lang.OutOfMemoryError: PermGen space`。该错误表明 Java 虚拟机 (JVM) 的永久...
Java中的“内存不足OOM (Out Of Memory):java.lang.OutOfMemoryError”是一个常见的运行时错误,它表示Java虚拟机(JVM)在尝试分配新的对象或数据结构时,发现系统内存不足以完成此操作。这个问题通常发生在程序...
Java程序在运行过程中可能会遇到各种异常,其中"nested exception is java.lang.OutOfMemoryError: Java heap space"是一个常见的问题,通常发生在程序试图分配超过堆内存限制的空间时。这个错误表明Java虚拟机(JVM...
OutOfMemoryError的8种经典案例,Java heap space、GC overhead limit exceeded、Permgen space、Metaspace、Unable to create new native thread、Out of swap space?、Requested array size exceeds VM limit、...
java.lang.OutOfMemoryError: Java heap space 解决方法