Showing posts with label memory. Show all posts
Showing posts with label memory. Show all posts

Sunday, June 12, 2011

Memory Leak : static collection object may be the reason

A very simple example of a memory leak would be a java.util.Collection object (for example, a HashMap) that is acting as a cache but which is growing without any bounds.
public class MyClass {
  static HashSet myContainer = new HashSet();
  public void leak(int numObjects) {
    for (int i = 0; i < numObjects; ++i) {
    String leakingUnit = new String("this is leaking object: " + i);
    myContainer.add(leakingUnit);
  }
}

Now in the main method:
public static void main(String[] args) throws Exception {
{
  MyClass myObj = new MyClass();
  myObj.leak(100000); // One hundred thousand }
  System.gc();
}


In the above program, there is a class with the name MyClass which has a static reference to HashSet by the name of myContainer. In the main method of the class: MyClass, (in bold text) within which an instance of the class: MyClass is instantiated and its member operation: leak is invoked. This results in the addition of a hundred thousand String objects into the container: myContainer. After the program control exits the subscope, the instance of the MyClass object is garbage collected, because there are no references to that instance of the MyClass object outside that subscope. However, the MyClass class object has a static reference to the member variable called myContainer. Due to this static reference, the myContainer HashSet continues to persist in the Java heap even after the sole instance of the MyClass object has been garbage collected and, along with the HashSet, all the String objects inside the HashSet continue to persist, holding up a significant portion of the Java heap until the program exits the main method.

This program demonstrates a basic memory leaking operation involving an unbounded growth in a cache object. Most caches are implemented using the Singleton pattern involving a static reference to a top level Cache class as shown in this example.


Here is the GC information for you for the above snippet....

[GC 512K->253K(1984K), 0.0018368 secs]
[GC 765K->467K(1984K), 0.0015165 secs]
[GC 979K->682K(1984K), 0.0016116 secs]
[GC 1194K->900K(1984K), 0.0015495 secs]
[GC 1412K->1112K(1984K), 0.0015553 secs]
[GC 1624K->1324K(1984K), 0.0014902 secs]
[GC 1836K->1537K(2112K), 0.0016068 secs]
[Full GC 1537K->1537K(2112K), 0.0120419 secs]
[GC 2047K->1824K(3136K), 0.0019275 secs]
[GC 2336K->2035K(3136K), 0.0016584 secs]
[GC 2547K->2248K(3136K), 0.0015602 secs]
[GC 2760K->2461K(3136K), 0.0015517 secs]
[GC 2973K->2673K(3264K), 0.0015695 secs]
[Full GC 2673K->2673K(3264K), 0.0144533 secs]
[GC 3185K->2886K(5036K), 0.0013183 secs]
[GC 3398K->3098K(5036K), 0.0015822 secs]
[GC 3610K->3461K(5036K), 0.0028318 secs]
[GC 3973K->3673K(5036K), 0.0019273 secs]
[GC 4185K->3885K(5036K), 0.0019377 secs]
[GC 4397K->4097K(5036K), 0.0012906 secs]
[GC 4609K->4309K(5036K), 0.0017647 secs]
[GC 4821K->4521K(5036K), 0.0017731 secs]
[Full GC 4521K->4521K(5036K), 0.0222485 secs]
[GC 4971K->4708K(8012K), 0.0042461 secs]
[GC 5220K->4920K(8012K), 0.0018258 secs]
[GC 5432K->5133K(8012K), 0.0018648 secs]
[GC 5645K->5345K(8012K), 0.0018069 secs]
[GC 5857K->5558K(8012K), 0.0017825 secs]
[GC 6070K->5771K(8012K), 0.0018911 secs]
[GC 6283K->5984K(8012K), 0.0016350 secs]
[GC 6496K->6197K(8012K), 0.0020342 secs]
[GC 6475K->6312K(8012K), 0.0013560 secs]
[Full GC 6312K->6118K(8012K), 0.0341375 secs]
[GC 6886K->6737K(11032K), 0.0045417 secs]
[GC 7505K->7055K(11032K), 0.0027473 secs]
[GC 7823K->7374K(11032K), 0.0028045 secs]
[GC 8142K->7693K(11032K), 0.0029234 secs]
[GC 8461K->8012K(11032K), 0.0027353 secs]
[GC 8780K->8331K(11032K), 0.0027790 secs]
[GC 9099K->8651K(11032K), 0.0028329 secs]
[GC 9419K->8970K(11032K), 0.0027895 secs]
[GC 9738K->9289K(11032K), 0.0028037 secs]
[GC 10057K->9608K(11032K), 0.0028161 secs]
[GC 10376K->9927K(11032K), 0.0028482 secs]
[GC 10695K->10246K(11032K), 0.0028858 secs]
[GC 11014K->10565K(11416K), 0.0029284 secs]
[Full GC 10565K->10565K(11416K), 0.0506198 secs]
[GC 11781K->11071K(18956K), 0.0035594 secs]
[GC 12287K->11577K(18956K), 0.0042315 secs]
[GC 12793K->12082K(18956K), 0.0043194 secs]
[GC 12843K->12390K(18956K), 0.0030633 secs]
[GC 13606K->13494K(18956K), 0.0085937 secs]
[Full GC 13782K->13613K(18956K), 0.0646513 secs]

Monday, April 25, 2011

Playing with JVM heam size

Java programs executes in JVM uses Heap of memory to manage the data. If your Java program requires a large amount of memory, it is possible that the virtual machine will begin to throw OutOfMemoryError instances when attempting to instantiate an object. The default heap size if 1 MB and can increase as much as 16 MB.

Java heap space setting from command line:
  1. -Xms for initial heap size
  2. -Xmx for maximum heap size 
  3. -Xss<size>   for set java stack size
     


Initial heap size 128m, max heap size 256m:
java -Xms128m -Xmx256m MyApp


Initial heap size 256m, max heap size 256m:
java -Xms128m -Xmx256m MyApp


Max heap size can't be less than initial heap size:
java -ms256m -mx128m MyAppError occurred during initialization of VM
Incompatible initial and maximum heap sizes specified

Tuesday, April 19, 2011

Java memory frames

Java Frames are a particularly important concept. Here's are a few bullet point definitions of a Java Frame:

  • A frame is used to store data and partial results, as well as to perform dynamic linking, return values for methods, and dispatch exceptions.
  • A new frame is created each time a method is invoked. A frame is destroyed when its method invocation completes.
  • Frames are allocated from the JVM stack of the thread creating the frame. Each frame has its own array of local variables, its own operand stack, and a reference to the runtime constant pool of the class of the current method.
  • The sizes of the local variable array and the operand stack are determined at compile time and are supplied along with the code for the method associated with the frame.
  • Only one frame, the frame for the executing method, is active at any point in a given thread of control. This frame is referred to as the current frame, and its method is known as the current method. The class in which the current method is defined is the current class.
  • A frame ceases to be current if its method invokes another method or if its method completes.
  • A frame created by a thread is local to that thread and cannot be referenced by any other thread.

There's more than this to know about Java Frames, but I tried to whittle the Sun description down to make it easier to digest initially.

Monday, April 18, 2011

Getting heap memory size in Java program


// Get current size of heap in bytes
long heapSize = Runtime.getRuntime().totalMemory()
Runtime.getRuntime().totalMemory();

// Get maximum size of heap in bytes. The heap cannot grow beyond this size.
// Any attempt will result in an OutOfMemoryException.
long heapMaxSize = Runtime.getRuntime().maxMemory();

// Get amount of free memory within the heap in bytes. This size will increase
// after garbage collection and decrease as new objects are created.
long heapFreeSize = Runtime.getRuntime().freeMemory();

Sunday, April 17, 2011

Address of a Java Object

Java has no pointers, but still there are methods which let us know address of objects.
Unsafe is a class that belongs to sun.misc package, to which may be you are new.

When a class name is “Unsafe” in java, it calls for your attention immediately. Then I decided to dig deep into it and find what is unsafe about that class. Its difficult to find the source of Unsafe. Get the source and look at the methods you will know what I am referring to.

Java’s security manager provides sufficient cover and ensures you don’t fiddle with memory that easily. As a first step, I thought of getting the memory location of a java object. But lets see.

Sun’s Unsafe.java api documentation shows us an opportunity to get the address using the method objectFieldOffset. That method says, “Report the location of a given field in the storage allocation of its class“. It also says, “it is just a cookie which is passed to the unsafe heap memory accessors“. Whatsoever, I am able to get the storage memory location of an object from the storage allocation of its class.

You can argue that, what we have got is not the absolute physical memory address of an object. But we have got the logical memory address. The following program will be quite interesting for you!
The program had following steps:

  • As a first step, I have to get an object of Unsafe class. It is quite difficult as the constructor is private. 
  • There is a method named getUnsafe which returns the unsafe object. Java’s security manager asks you to make your java source code privileged. I used little bit of reflection and got an instance out. I know there are better ways to get the instance. But to bypass the security easily I chose the following.
  • Using Unsafe’s object just invoke objectFieldOffset and staticFieldOffset. The result is address / location of object in the storage allocation of its class.

Following example program runs well on JDK 1.6:

import sun.misc.Unsafe;
import java.lang.reflect.Field;
public class ObjectLocation {
 private static int apple = 10;
 private int orange = 10;
 public static void main(String[] args)throws Exception {
  Unsafe unsafe = getUnsafeInstance();
  Field appleField = ObjectLocation.class.getDeclaredField("apple");
  System.out.println("Location of Apple: "
    + unsafe.staticFieldOffset(appleField));
  Field orangeField = ObjectLocation.class.getDeclaredField("orange");
  System.out.println("Location of Orange: "
    + unsafe.objectFieldOffset(orangeField));
 }
 private static Unsafe getUnsafeInstance()throws SecurityException,
   NoSuchFieldException, IllegalArgumentException,
   IllegalAccessException {
  Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
  theUnsafeInstance.setAccessible(true);
  return (Unsafe) theUnsafeInstance.get(Unsafe.class);
 }
}

JVM - heap, non heap memory and other terminologies

Java has only two types of memory when it comes to JVM. Heap memory and Non-heap memory. All the other memory jargons you hear are logical part of either of these two.

Heap Memory
In lay man's term class instances and arrays are stored in heap memory. Heap memory is also called as shared memory. As this is the place where multiple threads will share the same data.

Some points to consider:

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 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.

Non-heap Memory
It comprises of ‘Method Area’ and other memory required for internal processing. So here the major player is ‘Method Area’.

Method Area
As given in the last line, method area is part of non-heap memory. It stores per-class structures, code for methods and constructors. Per-class structure means runtime constants and static fields.

The above three (heap memory, non-heap memory and method area) are the main jargon when it comes to memory and JVM. There are some other technical jargon you might have heard and I will summarize them below.

Memory Pool
Memory pools are created by JVM memory managers during runtime. Memory pool may belong to either heap or non-heap memory.

Runtime Constant Pool
A run time constant pool is a per-class or per-interface run time representation of the constant_pool table in a class file. Each runtime constant pool is allocated from the Java virtual machine’s method area.

Java Stacks or Frames
Java stacks are created private to a thread. Every thread will have a program counter (PC) and a java stack. PC will use the java stack to store the intermediate values, dynamic linking, return values for methods and dispatch exceptions. This is used in the place of registers.
Definition of stack:

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. 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.


See more on frames


Memory Generations
HotSpot VM’s garbage collector uses generational garbage collection. It separates the JVM’s memory into and they are called young generation and old generation.

Young Generation
Young generation memory consists of two parts, Eden space and survivor space. Shortlived objects will be available in Eden space. Every object starts its life from Eden space. When GC happens, if an object is still alive and it will be moved to survivor space and other dereferenced objects will be removed.

Old Generation – Tenured and PermGen
Old generation memory has two parts, tenured generation and permanent generation (PermGen). PermGen is a popular term. We used to error like PermGen space not sufficient.
GC moves live objects from survivor space to tenured generation. The permanent generation contains meta data of the virtual machine, class and method objects.

Discussion:
Java specification doesn’t give hard and fast rules about the design of JVM with respect to memory. So it is completely left to the JVM implementers. The types of memory and which kind of variable / objects and where they will be stored is specific to the JVM implementation.


Key Takeaways

  • Local Variables are stored in Frames during runtime.
  • Static Variables are stored in Method Area.
  • Arrays are stored in heap memory.


References:

Sunday, February 27, 2011

Chitika