Java Memory Overflow (OOM) exception Complete guide

Source: Internet
Author: User
Tags system log throwable gc overhead limit exceeded

This is perhaps the most complete solution to the Java Oom exception. 1. Java.lang.OutOfMemoryError:Java Heap Spacejava The application will specify the required memory size at startup, and it is split into two different zones: heap Space (heap space) and PermGen (permanent Generation): JVM memory model The size of these two zones can be set by parameters-xmx and-xx:maxpermsize when the JVM (Java Virtual machine) starts, and if you do not explicitly set, the default values for the specific platform will be used. The Java.lang.OutOfMemoryError:Java heap space exception is triggered when an application attempts to add more data to the heap space, but the heap does not have enough space to accommodate the data. It is important to note that even if sufficient physical memory is available, this exception will still be triggered as long as the size limit of the heap space setting is reached. Cause analysis The most common reason for triggering java.lang.OutOfMemoryError:Java heap space is that the application requires a heap size of XXL, but the JVM supplies the S number. The workaround is simple enough to provide a larger heap space. In addition to the preceding factors there are more complex causes:
    • Peak Traffic/Data volume: The application at the beginning of the design of the user and data limits, a moment when the number of users or the amount of data suddenly reached a peak, and this peak has exceeded the threshold expected at the beginning of the design, the previous normal function will be stopped, and triggers the Java.lang.OutOfMemoryError:Java heap space exception.
    • Memory leaks: Specific programming errors can cause your application to consume more memory, and each time a feature with a memory leak risk leaves some objects that cannot be recycled into the heap space, and over time, the leaking objects consume all of the heap space. The Java.lang.OutOfMemoryError:Java heap space error is eventually triggered.
Example ①, the simple example begins with a very simple example, and the following code attempts to create an integer array of 2 x 1024 elements, when you attempt to compile and specify the 12M heap space Runtime (java-xmx12m OOM) will fail and throw a Java.lang.OutOfMemoryError:Java heap space error, and will run normally when you specify a 13M heap.
computed arrays occupy memory size, no longer within the scope of this article, readers are interested and can calculate their own
Class OOM {static final int size=2*1024*1024;public static void main (string[] a) {int[] i = new int[size];}} Run as follows: D:\>javac oom.javad:\>java-xmx12m oomexception in thread "main" Java.lang.OutOfMemoryError:Java heap Spaceat Oom.main (oom.java:4) d:\>java-xmx13m Oom②, memory leak example in Java, when a developer creates a new object (for example: New Integer (5)), it does not need to open up memory space, Instead, give it to the JVM. Throughout the application life cycle class, the JVM is responsible for checking which objects are available and which objects are not used. Unused objects are discarded, and the memory they occupy is also recycled, a process known as garbage collection. The collection of modules for garbage collection by the JVM is called the Garbage collector (GC). The automatic memory management mechanism of Java relies on the GC to periodically find unused objects and delete them. The memory leak in Java is due to the fact that the GC does not recognize objects that are no longer in use and that these unused objects remain in the heap space, which eventually results in Java.lang.OutOfMemoryError:Java heap spaces errors. We can easily write the Java code that caused the memory leak: public class Keylessentry { static class Key {integer id; key (integer id) {this.id = i D;}   @Overridepublic int hashcode () {return Id.hashcode ();}}  public static void Main (string[] args) {map<key,string> m = new hashmap<key,string> (); while (true) {for (int i=0;i<10000;i++) {if (!m.containskey (new key (i))) {M.put (new key (i), "number:" + i);}}}} The code HASHMAP for the local cache, the first time While loop, 10,000 elements are added to the cache. In the later while loop, the size of the cache will remain at 10000 because the key already exists in the cache. But is that really the case? Because the Key entity does not implement the Equals () method, the result of each execution of M.containskey (new Key (i)) in the For loop is false, and the result is that the elements in the HashMap will always increase. Over time, more and more key objects go into the heap space and cannot be reclaimed by the garbage collector (M is a local variable, the GC will assume that these objects are always available, so it will not be recycled) until all the heap space is occupied and the last throw Java.lang.OutOfMemoryError: Java Heap space.
The above code can run for a long time and will not throw an exception, use the-XMX parameter at startup, set the heap memory size, or print the size of the HashMap after the for loop, and you will find that HashMap's size has grown again after execution.
The workaround is also very simple, as long as Key implements its own Equals method: Overridepublic boolean equals (Object O) {Boolean response = False;if (o instanceof Key) {R Esponse = (((Key) O). id). Equals (This.id); return response;} Solution The first solution is obvious, you should make sure there is enough heap space to run your application properly, add the following configuration in the JVM's boot configuration:-xmx1024m above configuration allocates 1024M heap space to your application, of course you can also use other units, For example, G means gb,k represents KB. The following example indicates that the maximum heap space is 1gb:java-xmx1073741824 com.mycompany.myclassjava-xmx1048576k com.mycompany.myclassjava-xmx1024m COM.MYCOMPANY.MYCLASSJAVA-XMX1G Com.mycompany.MyClass Then, more often, simply adding heap space does not solve all the problems. If your program has a memory leak, simply increasing the heap space will only delay the Java.lang.OutOfMemoryError:Java heap spaces error occurred, did not resolve the hidden danger. In addition, when the garbage collector is in GC, the application stops running until the GC finishes, and increasing the heap space can also cause the GC time to lengthen, which in turn affects the program's throughput. If you want to completely solve this problem, then you have to improve your programming skills, of course, the use of debuggers, profilers, heap dump analyzers and other tools, you can maximize the program to avoid memory leak problems. 2. The Java.lang.OutOfMemoryError:GC overhead limit Exceededjava Runtime Environment (JRE) contains a built-in garbage collection process, and in many other programming languages, developers need to manually allocate and free memory. Java applications require only the developer to allocate memory, and a separate garbage collection process empties the memory space whenever a particular space in memory is no longer in use. How the garbage collector detects that some space in memory is no longer in use is beyond the scope of this article, but you just have to trust that the GC can do the job. By default, when an application spends more than 98% of its time using a GC and reclaims less than 2% of the heap memory, it throwsOut Java.lang.OutOfMemoryError:GC overhead limit exceeded error. The specific performance is that your app consumes almost all available memory, and the GC has failed to clean up many times. Reason analysis Java.lang.OutOfMemoryError:GC overhead limit exceeded error is a signal that your application spends too much time on garbage collection but has no eggs. This error is thrown when the default is more than 98% of the time used to do GC and less than 2% of the memory is reclaimed. What happens if there is no such limit? The GC process will be restarted, and 100% of the CPU will be used for GC, without CPU resources for other normal work. If a job would have taken just a few milliseconds and now it would take a few minutes to complete, I don't think anyone would be able to accept it. So Java.lang.OutOfMemoryError:GC overhead limit exceeded can also be seen as an example of a fail-fast (fast-failing) combat. The following code initializes a map and adds a key-value pair continuously in an infinite loop, and then throws a GC overhead limit exceeded error after running: public class Wrapper {public static void main (String Args[]) throws Exception {map map = system.getproperties (); Random r = new Random (), while (true) {Map.put (R.nextint (), "value");}}} As you might expect, the program does not end properly, in fact, when we start the program with the following parameters: JAVA-XMX100M-XX:+USEPARALLELGC Wrapper we can soon see the program throws Java.lang.OutOfMemoryError:GC overhead limit exceeded error. However, if you set a different heap size at startup or use a different GC algorithm, such as this: JAVA-XMX10M-XX:+USEPARALLELGC wrapper we will see the following error: Exception in thread "main" Java.lang.OutOfMemoryError:Java Heap Spaceat Java.util.Hashtable.rehash (UnknownSOURCE) at Java.util.Hashtable.addEntry (Unknown source) at Java.util.Hashtable.put (Unknown source) at Cn.moondev.Wrapper.main (WRAPPER.JAVA:12) uses the following GC algorithm:-XX:+USECONCMARKSWEEPGC or-XX:+USEG1GC, the startup command is as follows: Java-xmx100m-xx: +USECONCMARKSWEEPGC WRAPPERJAVA-XMX100M-XX:+USEG1GC Wrapper Get the result is this: Exception:java.lang.OutOfMemoryError thrown fromthe Uncaughtexceptionhandler in thread "main" error has been caught by the default exception handler, and there is no error in the stack information output. These changes can indicate that, in the case of limited resources, you simply can't predict how your app hangs and when it will hang up, so you can't just make sure your application is working in a particular environment when you develop it. The solution is first and foremost a no-good solution, and if you just don't want to see the Java.lang.OutOfMemoryError:GC overhead limit exceeded error message, you can add the following JVM parameters when the application starts:-xx:- Usegcoverheadlimit However, it is highly recommended not to use this option because it does not solve any problems, it only delays the time of the error, and the error message becomes the more familiar Java.lang.OutOfMemoryError:Java heap Space only. Another solution, if your application does not have enough memory, increasing the heap memory will solve the GC overhead limit problem, just as below, give your application 1G of heap memory: java-xmx1024m Com.yourcompany.YourClass But if you want to make sure that you have solved the potential problem instead of covering up Java.lang.OutOfMemoryError:GC overhead limit exceeded error, Then you shouldn't just stop here. You have to remember profilers and memory dump analyzers These tools, you need to spend more time and effort to find the problem. It is also important to note thatThese tools have significant overhead in the Java runtime and are therefore not recommended for use in production environments. 3. The heap space in Java.lang.OutOfMemoryError:Permgen Spacejava is the largest memory space managed by the JVM and can specify the size of the heap space when the JVM is started. The heap is divided into two different regions: the new Generation (young) and the Old Generation (tenured), and the Cenozoic is divided into 3 regions: Eden, from Survivor and to Survivor, as shown. Image source: Concurrent Programming Network Java.lang.OutOfMemoryError:PermGen Space error indicates that the memory of the region where the persistence generation is running is exhausted. Reason analysis to understand why Java.lang.OutOfMemoryError:PermGen space appears, first of all need to understand the usefulness of permanent Generation space. The primary storage for persistent generations is the information for each class, such as: class loader reference, run a constant pool (all constants, field references, method references, properties), method bytecode, and so on. We can infer that the size of the PermGen depends on the number of classes being loaded and the size of the class. Therefore, we can conclude that the cause of the Java.lang.OutOfMemoryError:PermGen space error is that too many classes or too large classes are loaded into the permanent generation (persistent generation). Example ①, the simplest example, as described earlier, the use of PermGen is closely related to the number of classes loaded into the JVM, and here is one of the simplest examples: import javassist. Classpool;public class Microgenerator {public static void main (string[] args) throws Exception {for (int i = 0; i < 100 _000_000; i++) {Generate ("Cn.moondev.User" + i);}}  public static Class Generate (String name) throws Exception {Classpool pool = Classpool.getdefault (); return Pool.mak EClass (name). Toclass ();}} At runtime, set the JVM parameter:-xx:maxpermsize=5m, the smaller the value, the better. It is important to note that JDK8 has completely removed the persistent generation space, instead of the meta-space (Metaspace), which is the best example of JDK1.7 or 1.6 running. The code generates the class at run time and loads it into the persistence generation until it is full of persistent memory space and finally throws Java.lang.OutOfMemoryError:Permgen space. The generation of classes in the code uses the Javassist library. One of the more complex and practical examples of ②, Redeploy-time is redeploy (re-deployment, you can imagine the process of tapping the Eclipse's Reploy button when you're developing, or by pressing CTRL + F5 when you use idea). When uninstalling an application from the server, the current ClassLoader and the loaded class will be cleaned up and reclaimed by the GC in the case of no instance reference. If an instance of the class in the application has a reference to the current ClassLoader, then the class in the PermGen area cannot be unloaded, causing the memory in the PermGen area to increase until the PermGen space error occurs. Unfortunately, many third-party libraries and bad resource handling methods (such as threads, JDBC drivers, file system handles) make it possible to unload previously usedThe ClassLoader has become an impossible thing. This, in turn, means that in each redeployment process, the previous versions of all of the application's classes will still reside in the PermGen zone, and each deployment will generate dozens of or even hundreds of m of garbage. It's all about threading and JDBC drivers. Many people use threads to handle recurring or lengthy tasks, so be aware of the thread's life cycle issues, and you need to make sure that the thread doesn't live longer than your application. Otherwise, if the application has been uninstalled and the thread continues to run, the thread will typically maintain a classloader reference to the application, resulting in no more talk. Say one more thing, developers have a responsibility to deal with this problem, especially if you are a third-party repository provider, be sure to provide a thread-close interface to handle cleanup work. Let's imagine a sample application that uses the JDBC driver to connect to a relational database. When an application is deployed to a server: The server creates an ClassLoader instance to load all classes of the application (including the corresponding JDBC driver). According to the JDBC specification, the JDBC driver (for example: com.mysql.jdbc.Driver) registers itself with the Java.sql.DriverManager when it is initialized. During the registration process, an instance of the driver is stored in the static field of the DriverManager, and the code can refer to://Com.mysql.jdbc.Driver Source Package Com.mysql.jdbc; public Class Driver extends Nonregisteringdriver implements Java.sql.Driver {public Driver () throws SQLException {}static {try {D Rivermanager.registerdriver (New Driver ());} catch (SQLException var1) {throw new RuntimeException ("can\ ' t Register driver!");}}} //////////////////see DriverManager corresponding code private final static copyonwritearraylist<driverinfo> registered Drivers = new copyonwritearraylist<> ();  public static synchronized void Registerdriver (java.sql.Driver Driver,driveraction da) throws SQLException {if (driver! = null) {registereddrivers.addifabsent (new Driverinfo (Driver, DA));} else {throw new NullPointerException ();}} Now, when uninstalling the application from the server, Java.sql.DriverManager will still hold a reference to that driver, which holds the C for loading the application.A reference to an instance of Lassloader. This classloader still references all classes of the application. If this program starts with 2000 classes to load and consumes approximately 10MB of permanent generation (PermGen) memory, then only 5~10 redeployment will be required, and the default size of the permanent generation (PermGen) is filled. The Java.lang.OutOfMemoryError:PermGen space error is then triggered and crashes. Solution ① resolves outofmemoryerror when initializing, the solution is simple when the outofmemoryerror caused by permgen exhaustion is triggered during application startup. The application needs more space to load all the classes into the PermGen area, so we just need to increase its size. To do this, change the application startup configuration and add (or increase, if present) the-xx:maxpermsize parameter, similar to the following example: java-xx:maxpermsize=512m Com.yourcompany.yourclass② OutOfMemoryError analysis dump file when resolving redeploy: First, find out where the reference is held; Next, add a closed hook to your Web application, or remove the reference after the application unloads. You can export the dump file using the following command: Jmap-dump:format=b,file=dump.hprof <process-id> If it is your own code problem, please modify, if it is a third-party library, please try to find out if there is a "close" interface, if you do not submit a bug or issue to the developer. ③ Resolving runtime OutOfMemoryError First you need to check whether the GC is allowed to unload classes from PermGen, the JVM's standard configuration is fairly conservative, and as soon as Class one is created, even if no instance references them, it remains in memory. In particular, when an application needs to dynamically create a large number of classes, but its life cycle is not long, allowing the JVM to unload classes is useful for applications, which you can do by adding the following configuration parameters to the startup script:-xx:+cmsclassunloadingenabled by default, This configuration is not enabled, and if you enable it, the GC will scan the PermGen area and clean up classes that are no longer in use. Note, however, that this configuration only takes effect in the case of USECONCMARKSWEEPGC, which is not valid if you are using other GC algorithms, such as PARALLELGC or serial GC. So when using the above configuration, please match:-XX:+USECONCMARKSWEEPGC if youHave ensured that the JVM can unload the class, but there is still a memory overflow problem, then you should continue to parse the dump file and generate the dump file using the following command: Jmap-dump:file=dump.hprof,format=b <process-id> When you get the generated heap dump file and use a tool like Eclipse Memory Analyzer Toolkit to find the ClassLoader that should be unloaded without being unloaded, then troubleshoot classes loaded by that ClassLoader, find suspicious objects, analyze the code that uses or generate these classes, Find the root cause of the problem and fix it. 4, Java.lang.OutOfMemoryError:Metaspace the previous article has been mentioned, the PermGen region is used to store the class name and field, class method, method bytecode, constant pool, JIT optimization, etc., but starting from Java8, The memory model in Java has changed significantly: A new area of memory called Metaspace has been introduced, and the PermGen region has been removed. Note: Instead of simply moving the contents of the PermGen area directly to the Metaspace area, some parts of the PermGen area have been moved to the normal heap. Oom-example-metaspace, photo source: plumbr Cause analysis Java8 reasons for such changes include, but are not limited to:
    The size of the PermGen area required by the
    • application is difficult to predict, the setting is too small to trigger PermGen outofmemoryerror errors, and excessive provisioning results in wasted resources.
    • promotes GC performance, and each garbage collector in the hotspot requires specialized code to handle the metadata information of classes stored in PermGen. Separating the metadata information from the PermGen class into Metaspace, because the Metaspace allocation has the same address space as the Java heap, the Metaspace and Java heap can be managed seamlessly, and the FULLGC process is simplified. Even in the future, metadata information can be garbage collected in parallel without a GC pause.
    • supports further optimizations, such as the G1 of concurrent classes, as well as preparing for the future.
As you can see, the requirement for the size of the meta-space depends on the number of classes loaded and the size of this class declaration. So it is easy to see the main reason for Java.lang.OutOfMemoryError:Metaspace: too many classes or too large classes to load into the meta space. As explained earlier in this example, the use of the meta-space is closely related to the number of classes loaded into the JVM. The following code is the simplest example: public class Metaspace {static javassist. Classpool CP = Javassist. Classpool.getdefault ();  public static void Main (string[] args) throws exception{for (int i = 0;; i++) {Class c = cp. Makeclass ("eu.plumbr.demo.Generated" + i). Toclass (); System.out.println (i);}}} New classes are generated during the run of the program, and all definitions of these classes are loaded into the Metaspace area until the space is fully occupied and the Java.lang.OutOfMemoryError:Metaspace is thrown. When you start with-xx:maxmetaspacesize = 32m, you will panic when you load more than 30,000 classes. 3102331024Exception in thread "main" javassist. Cannotcompileexception:by java.lang.OutOfMemoryError:Metaspaceat javassist. Classpool.toclass (classpool.java:1170) at Javassist. Classpool.toclass (classpool.java:1113) at Javassist. Classpool.toclass (classpool.java:1071) at Javassist. Ctclass.toclass (ctclass.java:1275) at Cn.moondev.book.Metaspace.main (metaspace.java:12) ..... Solution The first solution is obvious, since the application runs out of metaspace space in memory, it should increase its size, and change the boot configuration by adding the following parameters://Tell the JVM: Metaspace allowed to grow to 512 before throwing an exception-xx:maxmetaspacesize = 512m Another method is to remove this parameter to completely de-limit the size of the metaspace (there is no limit by default). By default, the default size for a 64-bit server-side jvm,metaspacesize is 21M (the initial limit), and once this limit is reached, FULLGC will be triggered to unload the class, and the limit value will be reset, and the new limit depends on the remaining capacity of the metaspace. If there is not enough space to be released, this limit will rise and vice versa. Technically metaspace size can grow to swap space, and this time local memory allocation will fail (more specific analysis, you can refer to: Where is Java PermGen?). You can "quickly fix" these memory overflow errors by modifying various startup parameters, but you need to correctly differentiate whether you just delay or hide the symptoms of java.lang.OutOfMemoryError. If your application does have a memory leak or is already loaded with some unreasonable classes, then all of these configurations are just the time to postpone the problem and actually not improve anything. 5, java.lang.OutOfMemoryError:Unable to create new native thread a way to think about a thread is to look at the worker who is performing the task, and if you have only one worker, then he can only perform one task, But if you have more than 10 workers, you can accomplish several tasks at the same time. Just as these workers are in the physical world, threads in the JVM will need some space to do their work, and when there are enough threads but not so much space, it would look like this: Picture Source: Plumbr appears java.lang.OutOfMemoryError:Unable to The Create new native thread means that the Java application has reached its limit of the number of threads it can start. Cause analysis When the JVM creates a new thread to the OS request, and the OS fails to create a new native thread, it throws the unable to create new native thread error. The number of threads a server can create depends on the physical configuration and platform, and it is recommended to run the sample code below to test the limitations. In general, this error is thrown through the following stages:
    • application that runs within the JVM requests that a new thread be created
    • the JVM creates a new native thread to the OS request
    • the OS tries to create a new native thread, and then allocates memory to the new thread
    • The
    • OS denies allocating memory to the thread because the 32-bit Java process has exhausted the memory address space (the 2-4GB memory address has been hit) or the OS's virtual memory is completely exhausted
    • Unable to create new native thread error will be thrown
Example the following example cannot create and start a new thread. When the code runs, it quickly reaches the OS thread limit and throws the unable to create new native thread error. while (true) {new Thread (new Runnable () {public void run () {try {thread.sleep (10000000);} catch (Interruptedexception e) {} }}). Start ();} Solution Sometimes, you can bypass this error by increasing the number of thread limits at the OS level. If you limit the number of threads that the JVM can create in user space, then you can check and increase this limit://MacOS 10.12 executes $ ulimit-u709 When your application generates thousands of threads and throws this exception, indicating that your program has already had a very serious programming error, I don't think we should fix this by modifying parameters, whether it's OS-level parameters or JVM startup parameters. The more desirable approach is to analyze whether your application really needs to create so many threads to complete the task? Is it possible to use the thread pool or the number of thread pools that are appropriate? Whether it can be more reasonable to split the business to achieve ..... 6. Java.lang.OutOfMemoryError:Out of swap space? Java applications specify the required memory size at startup, and can be specified by-XMX and other similar startup parameters. When the total memory requested by the JVM is greater than the available physical memory, the operating system exchanges the in-memory data to disk. Image source: Plumbrout of swap space? Indicates that swap spaces will also be exhausted, and attempts to allocate memory again will fail due to the lack of physical memory and swap space. Cause analysis when an application fails to allocate memory to the JVM native heap request and the native heap is about to run out, the JVM throws an out of swap space error. The error message contains the size (in bytes) of the allocation failure and the reason for the request to fail.
Native Heap memory is used inside the JVM memory, this part of memory can be accessed through the JNI provided by the JDK, this part of the memory is very efficient, but management needs to do their own, if not sure the best not to use, In case there is a memory leak problem. The JVM uses native Heap memory to optimize code loading (JTI code generation), temporary object space requests, and some operations within the JVM.
This problem often occurs when the Java process has started to exchange, the modern GC algorithm has done well enough, when faced with the delay caused by the exchange, GC pause time tends to make most applications intolerable. Java.lang.OutOfMemoryError:Out of swap space? is often caused by an operating system-level problem, such as:
    • The operating system configuration has insufficient swap space.
    • Another process on the system consumes all memory resources.
It is also possible that the local memory leak caused the application to fail, for example: the application called native code to allocate memory continuously, but it was not released. Solution to solve this problem there are several ways, usually the simplest way is to increase the exchange of space, the different platform implementation will vary, such as under Linux can be implemented by the following command: # The original use, because I do not have a Linux environment, so did not test # Create and attach a new swap file with a size of 640MB swapoff-add if=/dev/zero of=swapfile bs=1024 count=655360mkswap swapfileswapon Swapfilejava The GC scans the in-memory data and, if the garbage collection algorithm is run against the swap space, increases the time that the GC pauses by several orders of magnitude, so you should consider using the above method to increase swap space. If your application is deployed on a physical machine where the JVM needs to compete fiercely with other processes to get resources, it is recommended that you isolate the service to a separate virtual machine but in many cases, the only real alternative is:
    • Upgrade your machine to include more memory
    • Optimize your application to reduce its memory footprint
When you turn to optimized paths, it is a good start to use the memory dump parser to detect large allocations in memory. 7. The java.lang.OutOfMemoryError:Requested array size exceeds VM Limitjava has a limit on the maximum array size an application can allocate. Different platform limits vary, but typically between 1 and 2.1 billion elements. Image source: Plumbr When you encounter the requested array size exceeds VM limit error, it means that your application is trying to allocate an array that is larger than the Java Virtual machine can support. Cause analysis This error is thrown by native code in the JVM. Before the JVM allocates memory for an array, it performs platform-specific checks: whether the allocated data structure is addressable in this platform. You seldom see this error because the index of the Java array is of type int. The maximum positive integer in Java is 2 ^ 31-1 = 2,147,483,647. and platform-specific restrictions can be very close to this number, for example: my environment (64-bit MacOS, run Jdk1.8) can initialize an array of lengths up to 2,147,483,645 (integer.max_value-2). Increasing the length of the array by 1 to integer.max_value-1 will result in the familiar outofmemoryerror:exception in thread "main" Java.lang.OutOfMemoryError: Requested array size exceeds VM limit However, on 32-bit Linux that uses OPENJDK 6, when you allocate an array with approximately 1.1 billion elements, you will encounter requested array size exceeded VM Lim It's wrong. To understand the limitations of your particular environment, run the small test program described below. Example for (int i = 3; I >= 0; i--) {try {int[] arr = new Int[integer.max_value-i]; System.out.format ("successfully initialized an array with%,d elements.\n", integer.max_value-i);} catch (Throwable t) {t.printstacktrace ();}} The example repeats four times and initializes an array of long primitives in each turn. The program attempts to initializeThe size of the array increases by 1 at each iteration and eventually reaches Integer.max_value. Now, when you start a code snippet on 64-bit Mac OS x using hotspot 7, you should get output similar to the following: Java.lang.OutOfMemoryError:Java heap Spaceat Eu.plumbr.demo.ArraySize.main (arraysize.java:8) Java.lang.OutOfMemoryError:Java heap Spaceat Eu.plumbr.demo.ArraySize.main (arraysize.java:8) java.lang.OutOfMemoryError:Requested array size exceeds VM Limitat Eu.plumbr.demo.ArraySize.main (arraysize.java:8) java.lang.OutOfMemoryError:Requested array size exceeds VM Limitat Eu.plumbr.demo.ArraySize.main (Arraysize.java:8) Note that before the requested array size exceeded VM limit appears, The more familiar Java.lang.OutOfMemoryError:Java heap space appears. This is because initializing an array of 2 ^ 31-1 elements requires freeing up 8G of memory space, which is larger than the default value used by the JVM. Solution java.lang.OutOfMemoryError:Requested array size exceeds VM limit may appear in any of the following scenarios:
    The
    • array grows too large for the final size between platform limits and Integer.max_int
    • you intentionally allocate an array greater than 2 ^ 31-1 elements
In the first case, check your code base to see if you really need such a large array. Perhaps you can reduce the size of the array, or divide the array into smaller chunks and then process the data in batches. In the second case, remember that the Java array is indexed by Int. Therefore, when using standard data structures in the platform, the array cannot exceed 2 ^ 31-1 elements. In fact, there will be an error at compile time: Error:integer number too large. 8, out of Memory:kill process or sacrifice in order to understand this error, we need to add a little bit of operating system fundamentals. Operating systems are built on the concept of processes, which work in the kernel, with a very special process called "Memory Killer" (out of killer). When the kernel detects a low system memory, OOM killer is activated and a process is selected to kill. Which process is so unlucky? The choice of algorithms and ideas are simple: who occupies the most memory, who will be killed. If you are interested in Oom killer, it is recommended that you read the articles in reference 2. OOM Killer, Image source: PLUMBR when the available virtual virtual memory (including swap space) is consumed to the risk of the entire operating system, an out of memory:kill process or a sacrifice child error is generated. In this case, OOM killer will select "Rogue process" and kill it. Cause analysis By default, the Linux kernel allows processes to request more memory than is available in the system, but most processes do not actually use up their allocated memory. This is similar to real-life broadband operators, they sell a 100M bandwidth to all consumers, far more than the user actually use the bandwidth, a 10G link can be very easy to service 100 (10g/100m) users, But in reality, broadband operators tend to use 10G links to serve 150 or more, so that the link can be used more effectively, after all, it makes no sense to idle there. The Linux kernel uses a mechanism similar to that of a broadband operator, generally without problems, but when most applications consume their own memory, the trouble comes because the memory requirements of these applications add up beyond the capacity of physical memory (including swap) and the kernel (OOM Killer) Some processes must be killed to make room for the system to function properly. As in the above example, if 150 people occupy 100M of bandwidth, then the total bandwidth will certainly exceed the range that the 10G link can withstand. Example when you run the following code on Linux: public static void Main (STRIng[] args) {list<int[]> L = new java.util.ArrayList (); for (int i = 10000; i < 100000; i++) {try {l.add (new int[10 0000000]);} catch (Throwable t) {t.printstacktrace ();}}} The following log appears in the Linux system log/var/log/kern.log: June 4 07:41:59 plumbr kernel: [70667120.897649] out of Memory:kill process 29957 (ja VA) score 366 or sacrifice Childjun 4 07:41:59 plumbr kernel: [70667120.897701] killed process 29957 (Java) total-vm:25326 80kB, anon-rss:1416508kb, file-rss:0kb Note: You may need to adjust the swap file and heap size, otherwise you will soon see the familiar Java heap space exception. In the original author's test case, the 2g heap specified by-xmx2g is used, and has the following interchange configuration: # Note: The original author used, because I do not have a Linux environment, so did not test Swapoff-add If=/dev/zero of=swapfile bs=1024 Count=655360mkswap Swapfileswapon Swapfile Solution   The most effective and straightforward way to solve this problem is to upgrade the memory, other ways such as: Adjust the Oom killer configuration, scale the application horizontally, Allocate the load of memory on several small instances ..... We do not propose to increase the exchange of space, the specific reason has been mentioned in the previous article. Reference ② details how to fine-tune the Oom killer configuration and the implementation of the Oom killer selection process algorithm, which is recommended for you to read.

Java Memory Overflow (OOM) exception Complete guide (GO)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.