Java - OutOfMemoryError

java.lang.OutOfMemoryError is thrown when JVM is unable to allocate memory to create an object. Java OutOfMemoryError is an Error and occurs a runtime.

java.lang.OutOfMemoryError

As the name suggests, OutOfMemoryError occurs when java runtime is out of memory. In this case garbage collector is unable to free more space required by program and hence error is thrown.
There are two main reasons to get java.lang.OutOfMemoryError:
  1. Poor programming – infinite loop, not clearing memory by closing resources etc.
  2. Low Memory – java is running on less memory than required.

Java OutOfMemoryError – Poor Programming Example

Let’s look into a sample code that will throw java.lang.OutOfMemoryError: Java heap space because the program is going into infinite loop and objects are getting created but not getting garbage collected. So eventually JVM will run out of memory.

package com.journaldev.exceptions;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public classJavaOutOfMemoryErrorExample {

public static void main(String[] args) {
List<Integer> list = newArrayList<>();

Random random = new Random();

while (true)
list.add(random.nextInt());

}
}
When above code is executed, it will throw following exception after some time.

Exception in thread "main"java.lang.OutOfMemoryError: Java heap space
at java.base/java.lang.Integer.valueOf(Integer.java:1050)
at com.journaldev.exceptions.JavaOutOfMemoryErrorExample.main(JavaOutOfMemoryErrorExample.java:15)
java lang OutOfMemoryError java heap space
This is an example of poor programming, but the good news is that the exception stack trace clearly points us to look for the code where this error occurred. However sometimes the problem might be in some other areas of the program, in that case we will need help of java profilers such as VisualVM to figure out where most of the memory is being allocated and how to optimize it.

Java OutOfMemoryError – Low Memory Example

Let’s look at another example where the OutOfMemoryError is caused because we didn’t allocate enough memory for program to execute properly.

public classJavaOutOfMemoryErrorExample {

public static void main(String[] args) {

Integer[] array = newInteger[1000*1000*100];
System.out.println("Done");

}

}
Let’s see what happens when we run above program with JVM max memory limit of 32 MB.

$javacJavaOutOfMemoryErrorExample.java 
$java -Xmx32m JavaOutOfMemoryErrorExample
Exception in thread "main"java.lang.OutOfMemoryError: Java heap space
at JavaOutOfMemoryErrorExample.main(JavaOutOfMemoryErrorExample.java:5)
As we can see that there is nothing wrong in the program, we are running it on very low memory. Let’s try to fix this OutOfMemoryError by increasing the JVM memory to 256MB and then 512 MB.
$java -Xmx256m JavaOutOfMemoryErrorExample
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at JavaOutOfMemoryErrorExample.main(JavaOutOfMemoryErrorExample.java:5)
$java -Xmx512m JavaOutOfMemoryErrorExample
Done
$
So it seems that our program runs fine when we provide enough memory to run it.
Increasing the memory of JVM is a quick fix to solve the problem, unless you are running on very low memory. If you are already running on high JVM memory such as 2GB or more, then you should look into the application code to optimize it, look into thread dump and java profiler output to see why your application requires high memory and if you can reduce it.

How to solve java.lang.OutOfMemoryError: Java heap space


1) An easy way to solve OutOfMemoryError in java is to increase the maximum heap size by using JVM options "-Xmx512M", this will immediately solve your OutOfMemoryError. This is my preferred solution when I get OutOfMemoryError in Eclipse, Maven or ANT while building project because based upon size of project you can easily run out of Memory.here is an example of increasing maximum heap size of JVM, Also its better to keep -Xmx to -Xms ration either 1:1 or 1:1.5 if you are setting heap size in your java application

export JVM_ARGS="-Xms1024m -Xmx1024m"

2) The second way to resolve OutOfMemoryError in Java is rather hard and  comes when you don't have much memory and even after increase maximum heap size you are still getting java.lang.OutOfMemoryError, in this case, you probably want to profile your application and look for any memory leak. You can use Eclipse Memory Analyzer to examine your heap dump or you can use any profiler like Netbeans or JProbe. This is tough solution and requires some time to analyze and find memory leaks.





How to solve java.lang.OutOfMemoryError: PermGen space

As explained in above paragraph this OutOfMemory error in java comes when Permanent generation of heap filled up. To fix this OutOfMemoryError in Java, you need to increase heap size of Perm space by using JVM option   "-XX: MaxPermSize". You can also specify initial size of Perm space by using    "-XX: PermSize" and keeping both initial and maximum Perm Space you can prevent some full garbage collection which may occur when Perm Space gets re-sized. Here is how you can specify initial and maximum Perm size in Java:

export JVM_ARGS="-XX:PermSize=64M -XX:MaxPermSize=256m"

Some time java.lang.OutOfMemoryError  in Java gets tricky and on those cases profiling remains ultimate solution.Though you have the freedom to increase heap size in java, it’s recommended that to follow memory management practices while coding and setting null to any unused references.
That’s all from me on OutOfMemoryError in Java I will try to write more about finding the memory leak in java and using profiler in some other post. Please share what is your approach to solving java.lang.OutOfMemoryError in Java.


blog-space.html#ixzz6JiCZxL1J

How to Analyze Java Thread Dumps



read Dumps

 by 

Esen Sagynov







 ·

 Oct. 18, 12 ·Performance Zone · Tutorial

Like (78)



 Comment (37)



Save

 Tweet

The content of this article was originally written by Tae Jin Gu on the Cubrid blog. 

When there is an obstacle, or when a Java based Web application is running much slower than expected, we need to use thread dumps. If thread dumps feel like very complicated to you, this article may help you very much. Here I will explain what threads are in Java, their types, how they are created, how to manage them, how you can dump threads from a running application, and finally how you can analyze them and determine the bottleneck or blocking threads. This article is a result of long experience in Java application debugging.

Java and Thread

A web server uses tens to hundreds of threads to process a large number of concurrent users. If two or more threads utilize the same resources, a contention between the threads is inevitable, and sometimes deadlock occurs.

Thread contention is a status in which one thread is waiting for a lock, held by another thread, to be lifted. Different threads frequently access shared resources on a web application. For example, to record a log, the thread trying to record the log must obtain a lock and access the shared resources.

Deadlock is a special type of thread contention, in which two or more threads are waiting for the other threads to complete their tasks in order to complete their own tasks.

Different issues can arise from thread contention. To analyze such issues, you need to use the thread dump. A thread dump will give you the information on the exact status of each thread.

Background Information for Java ThreadsThread Synchronization

A thread can be processed with other threads at the same time. In order to ensure compatibility when multiple threads are trying to use shared resources, one thread at a time should be allowed to access the shared resources by using thread synchronization.

Thread synchronization on Java can be done using monitor. Every Java object has a single monitor. The monitor can be owned by only one thread. For a thread to own a monitor that is owned by a different thread, it needs to wait in the wait queue until the other thread releases its monitor.

Thread Status

In order to analyze a thread dump, you need to know the status of threads. The statuses of threads are stated on java.lang.Thread.State.

Figure 1: Thread Status.

NEW: The thread is created but has not been processed yet.RUNNABLE: The thread is occupying the CPU and processing a task. (It may be in WAITING status due to the OS's resource distribution.)BLOCKED: The thread is waiting for a different thread to release its lock in order to get the monitor lock.WAITING: The thread is waiting by using a wait, join or park method.TIMED_WAITING: The thread is waiting by using a sleep, wait, join or parkmethod. (The difference from WAITING is that the maximum waiting time is specified by the method parameter, and WAITING can be relieved by time as well as external changes.) Thread Types

Java threads can be divided into two:

daemon threads;and non-daemon threads.

Daemon threads stop working when there are no other non-daemon threads. Even if you do not create any threads, the Java application will create several threads by default. Most of them are daemon threads, mainly for processing tasks such as garbage collection or JMX.

A thread running the 'static void main(String[] args)’ method is created as a non-daemon thread, and when this thread stops working, all other daemon threads will stop as well. (The thread running this main method is called the VM thread in HotSpot VM.)

Getting a Thread Dump

We will introduce the three most commonly used methods. Note that there are many other ways to get a thread dump. A thread dump can only show the thread status at the time of measurement, so in order to see the change in thread status, it is recommended to extract them from 5 to 10 times with 5-second intervals.

Getting a Thread Dump Using jstack

In JDK 1.6 and higher, it is possible to get a thread dump on MS Windows using jstack.

Use PID via jps to check the PID of the currently running Java application process.

[user@linux ~]$ jps -v

25780 RemoteTestRunner -Dfile.encoding=UTF-8

25590 sub.rmi.registry.RegistryImpl 2999 -Dapplication.home=/home1/user/java/jdk.1.6.0_24 -Xms8m

26300 sun.tools.jps.Jps -mlvV -Dapplication.home=/home1/user/java/jdk.1.6.0_24 -Xms8m

Use the extracted PID as the parameter of jstack to obtain a thread dump.

[user@linux ~]$ jstack -f 5824

A Thread Dump Using jVisualVM

Generate a thread dump by using a program such as jVisualVM.

Figure 2:  A Thread Dump Using visualvm.

The task on the left indicates the list of currently running processes. Click on the process for which you want the information, and select the thread tab to check the thread information in real time. Click the Thread Dump button on the top right corner to get the thread dump file.

Generating in a Linux Terminal

Obtain the process pid by using ps -efcommand to check the pid of the currently running Java process.

[user@linux ~]$ ps - ef | grep java

user 2477 1 0 Dec23 ? 00:10:45 ...

user 25780 25361 0 15:02 pts/3 00:00:02 ./jstatd -J -Djava.security.policy=jstatd.all.policy -p 2999

user 26335 25361 0 15:49 pts/3 00:00:00 grep java

Use the extracted pid as the parameter of kill –SIGQUIT(3) to obtain a thread dump.

Thread Information from the Thread Dump File

"pool-1-thread-13" prio=6 tid=0x000000000729a000 nid=0x2fb4 runnable [0x0000000007f0f000] java.lang.Thread.State: RUNNABLE

at java.net.SocketInputStream.socketRead0(Native Method)

at java.net.SocketInputStream.read(SocketInputStream.java:129)

at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)

at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)

at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)

- locked <0x0000000780b7e688> (a java.io.InputStreamReader)

at java.io.InputStreamReader.read(InputStreamReader.java:167)

at java.io.BufferedReader.fill(BufferedReader.java:136)

at java.io.BufferedReader.readLine(BufferedReader.java:299)

- locked <0x0000000780b7e688> (a java.io.InputStreamReader)

at java.io.BufferedReader.readLine(BufferedReader.java:362)

)

Thread name: When using Java.lang.Thread class to generate a thread, the thread will be named Thread-(Number), whereas when using java.util.concurrent.ThreadFactory class, it will be named pool-(number)-thread-(number).Priority: Represents the priority of the threads.Thread ID: Represents the unique ID for the threads. (Some useful information, including the CPU usage or memory usage of the thread, can be obtained by using thread ID.)Thread status: Represents the status of the threads.Thread callstack: Represents the call stack information of the threads. Thread Dump Patterns by TypeWhen Unable to Obtain a Lock (BLOCKED)

This is when the overall performance of the application slows down because a thread is occupying the lock and prevents other threads from obtaining it. In the following example, BLOCKED_TEST pool-1-thread-1 thread is running with <0x0000000780a000b0> lock, while BLOCKED_TEST pool-1-thread-2 and BLOCKED_TEST pool-1-thread-3 threads are waiting to obtain <0x0000000780a000b0> lock.

Figure 3: A thread blocking other threads.

"BLOCKED_TEST pool-1-thread-1" prio=6 tid=0x0000000006904800 nid=0x28f4 runnable [0x000000000785f000]

java.lang.Thread.State: RUNNABLE

at java.io.FileOutputStream.writeBytes(Native Method)

at java.io.FileOutputStream.write(FileOutputStream.java:282)

at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)

at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)

- locked <0x0000000780a31778> (a java.io.BufferedOutputStream)

at java.io.PrintStream.write(PrintStream.java:432)

- locked <0x0000000780a04118> (a java.io.PrintStream)

at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)

at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272)

at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:85)

- locked <0x0000000780a040c0> (a java.io.OutputStreamWriter)

at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:168)

at java.io.PrintStream.newLine(PrintStream.java:496)

- locked <0x0000000780a04118> (a java.io.PrintStream)

at java.io.PrintStream.println(PrintStream.java:687)


ead dump, you can see that DEADLOCK_TEST-1 thread has 0x00000007d58f5e48 lock, and is trying to obtain 0x00000007d58f5e60 lock. You can also see that DEADLOCK_TEST-2 thread has 0x00000007d58f5e60 lock, and is trying to obtain 0x00000007d58f5e78 lock. Also, DEADLOCK_TEST-3 thread has 0x00000007d58f5e78 lock, and is trying to obtain 0x00000007d58f5e48 lock. As you can see, each thread is waiting to obtain another thread's lock, and this status will not change until one thread discards its lock.

Figure 4: Threads in a Deadlock status.



"DEADLOCK_TEST-1" daemon prio=6 tid=0x000000000690f800 nid=0x1820 waiting for monitor entry [0x000000000805f000]

java.lang.Thread.State: BLOCKED (on object monitor)

at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.goMonitorDeadlock(ThreadDeadLockState.java:197)

- waiting to lock <0x00000007d58f5e60> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)

at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.monitorOurLock(ThreadDeadLockState.java:182)

- locked <0x00000007d58f5e48> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)

at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.run(ThreadDeadLockState.java:135)

Locked ownable synchronizers:

- None

"DEADLOCK_TEST-2" daemon prio=6 tid=0x0000000006858800 nid=0x17b8 waiting for monitor entry [0x000000000815f000]

java.lang.Thread.State: BLOCKED (on object monitor)

at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.goMonitorDeadlock(ThreadDeadLockState.java:197)

- waiting to lock <0x00000007d58f5e78> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)

at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.monitorOurLock(ThreadDeadLockState.java:182)

- locked <0x00000007d58f5e60> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)

at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.run(ThreadDeadLockState.java:135)

Locked ownable synchronizers:

- None

"DEADLOCK_TEST-3" daemon prio=6 tid=0x0000000006859000 nid=0x25dc waiting for monitor entry [0x000000000825f000]

java.lang.Thread.State: BLOCKED (on object monitor)

at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.goMonitorDeadlock(ThreadDeadLockState.java:197)

- waiting to lock <0x00000007d58f5e48> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)

at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.monitorOurLock(ThreadDeadLockState.java:182)

- locked <0x00000007d58f5e78> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)

at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.run(ThreadDeadLockState.java:135)

Locked ownable synchronizers:

- None

When Continuously Waiting to Receive Messages from a Remote Server

The thread appears to be normal, since its state keeps showing as RUNNABLE. However, when you align the thread dumps chronologically, you can see that socketReadThread thread is waiting infinitely to read the socket.

Figure 5: Continuous Waiting Status.

"socketReadThread" prio=6 tid=0x0000000006a0d800 nid=0x1b40 runnable [0x00000000089ef000]

java.lang.Thread.State: RUNNABLE

at java.net.SocketInputStream.socketRead0(Native Method)

at java.net.SocketInputStream.read(SocketInputStream.java:129)

at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)

at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)

at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)

- locked <0x00000007d78a2230> (a java.io.InputStreamReader)

at sun.nio.cs.StreamDecoder.read0(StreamDecoder.java:107)

- locked <0x00000007d78a2230> (a java.io.InputStreamReader)

at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:93)

at java.io.InputStreamReader.read(InputStreamReader.java:151)

at com.nbp.theplatform.threaddump.ThreadSocketReadState$1.run(ThreadSocketReadState.java:27)

at java.lang.Thread.run(Thread.java:662)

When Waiting

The thread is maintaining WAIT status. In the thread dump, IoWaitThread thread keeps waiting to receive a message from LinkedBlockingQueue. If there continues to be no message for LinkedBlockingQueue, then the thread status will not change.

Figure 6: Waiting status.

"IoWaitThread" prio=6 tid=0x0000000007334800 nid=0x2b3c waiting on condition [0x000000000893f000]

java.lang.Thread.State: WAITING (parking)

at sun.misc.Unsafe.park(Native Method)

- parking to wait for <0x00000007d5c45850> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)

at java.util.concurrent.locks.LockSupport.park(LockSupport.java:156)

at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1987)

at java.util.concurrent.LinkedBlockingDeque.takeFirst(LinkedBlockingDeque.java:440)

at java.util.concurrent.LinkedBlockingDeque.take(LinkedBlockingDeque.java:629)

at com.nbp.theplatform.threaddump.ThreadIoWaitState$IoWaitHandler2.run(ThreadIoWaitState.java:89)

at java.lang.Thread.run(Thread.java:662)

When Thread Resources Cannot be Organized Normally

Unnecessary threads will pile up when thread resources cannot be organized normally. If this occurs, it is recommended to monitor the thread organization process or check the conditions for thread termination.

Figure 7: Unorganized Threads.

How to Solve Problems by Using Thread DumpExample 1: When the CPU Usage is Abnormally High

1. Extract the thread that has the highest CPU usage.

[user@linux ~]$ ps -mo pid.lwp.stime.time.cpu -C java

abnormal, the threads wait until the time is out. In this case, even after extracting the thread dumps several times and comparing them, you will see that the threads related to DBMS are still in a BLOCKED state. By adequately changing the values, such as the timeout value, you can shorten the time in which the problem occurs.

Coding for Easy Thread Dump

Naming Threads

When a thread is created using java.lang.Thread object, the thread will be named Thread-(Number). When a thread is created using java.util.concurrent.DefaultThreadFactory object, the thread will be named pool-(Number)-thread-(Number). When analyzing tens to thousands of threads for an application, if all the threads still have their default names, analyzing them becomes very difficult, because it is difficult to distinguish the threads to be analyzed.
Therefore, you are recommended to develop the habit of naming the threads whenever a new thread is created. 
When you create a thread using java.lang.Thread, you can give the thread a custom name by using the creator parameter.
public Thread(Runnable target, String name);
public Thread(ThreadGroup group, String name);
public Thread(ThreadGroup group, Runnable target, String name);
public Thread(ThreadGroup group, Runnable target, String name, long stackSize);
When you create a thread using java.util.concurrent.ThreadFactory, you can name it by generating your own ThreadFactory. If you do not need special functionalities, then you can use MyThreadFactory as described below:
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
public class MyThreadFactory implements ThreadFactory {
  private static final ConcurrentHashMap<String, AtomicInteger> POOL_NUMBER =
                                                       new ConcurrentHashMap<String, AtomicInteger>();
  private final ThreadGroup group;
  private final AtomicInteger threadNumber = new AtomicInteger(1);
  private final String namePrefix;
  public MyThreadFactory(String threadPoolName) {
      if (threadPoolName == null) {
          throw new NullPointerException("threadPoolName");
      }
            POOL_NUMBER.putIfAbsent(threadPoolName, new AtomicInteger());
      SecurityManager securityManager = System.getSecurityManager();
      group = (securityManager != null) ? securityManager.getThreadGroup() :
                                                    Thread.currentThread().getThreadGroup();
      AtomicInteger poolCount = POOL_NUMBER.get(threadPoolName);
      if (poolCount == null) {
            namePrefix = threadPoolName + " pool-00-thread-";
      } else {
            namePrefix = threadPoolName + " pool-" + poolCount.getAndIncrement() + "-thread-";
      }
  }
  public Thread newThread(Runnable runnable) {
      Thread thread = new Thread(group, runnable, namePrefix + threadNumber.getAndIncrement(), 0);
      if (thread.isDaemon()) {
            thread.setDaemon(false);
      }
      if (thread.getPriority() != Thread.NORM_PRIORITY) {
            thread.setPriority(Thread.NORM_PRIORITY);
      }
      return thread;
  }
}

Obtaining More Detailed Information by Using MBean

You can obtain ThreadInfo objects using MBean. You can also obtain more information that would be difficult to acquire via thread dumps, by using ThreadInfo.
ThreadMXBean mxBean = ManagementFactory.getThreadMXBean();
long[] threadIds = mxBean.getAllThreadIds();
ThreadInfo[] threadInfos =
                mxBean.getThreadInfo(threadIds);
for (ThreadInfo threadInfo : threadInfos) {
  System.out.println(
      threadInfo.getThreadName());
  System.out.println(
      threadInfo.getBlockedCount());
  System.out.println(
      threadInfo.getBlockedTime());
  System.out.println(
      threadInfo.getWaitedCount());
  System.out.println(
      threadInfo.getWaitedTime());
}
You can acquire the amount of time that the threads WAITed or were BLOCKED by using the method in ThreadInfo, and by using this you can also obtain the list of threads that have been inactive for an abnormally long period of time.

HotSpot JVM Options in Java


1) JVM memory options related to java heap size
Following three JVM options are used to specify initial and max heap size and thread stack size while running Java programs.

 -Xms        set initial Java heap size
 -Xmx        set maximum Java heap size
 -Xss>         set java thread stack size

6) JVM options related to java classpath
Xbootclasspath

7) JVM options to change  Perm Gen Size
These JVM optiosn are quite useful to solve java.lang.OutOfMemoryError:Perm Gen Space.

-XX:PermSize and MaxPermSize
-XX:NewRatio=2  Ratio of new/old generation sizes.
-XX:MaxPermSize=64m     Size of the Permanent Generation.


Read more: https://javarevisited.blogspot.com/2011/11/hotspot-jvm-options-java-examples.html#ixzz6JiE7FpcY
SHARE

esant technology

0 comments :

Post a Comment