Nov 15, 2017

Understanding JVM: Memory Areas in JVM - Part 3

We have already covered Method Area, Heap Area and Stack memory in previous articles. This article will give brief overview of the remaining 2 memory areas in JVM, i.e., PC Registers and Native Method Stack.

PC Register (Program Counter Registers)

  • It is internally used by JVM and like Stack Memory, every thread keeps a separate PC register, which is created at the time of thread creation.
  • It contains the address of currently executing instruction.
  • Once instruction execution completes, automatically PC register is incremented to hold the address of next instruction.

Native Method Stack

  • JVM creates a separate Native Method Stack per thread.
  • Again, it is internally used by JVM. All native calls invoked by thread will be stored in corresponding native method stack.

This concludes the topic of Memory Areas inside JVM. To summarize things:
  1. Method area, heap area and stack area are considered most important with respect to programmers.
  2. Method and heap area are per JVM.
  3. Stack memory, PC registers and Native Method stack are maintained per thread.
  4. Static variables are stored in Memory Area
  5. Instance variables are stored in Heap Area
  6. Local variables are stored in Stack Area

Let us write a simple program to understand things better: 

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
package edu.javaterritory.example.methodarea;

public class Test {

 private Student s1 = new Student();
 private static Student s2 = new Student();
 
 public static void main(String[] args) {
  Test t1 = new Test();
  Student s3 = new Student();
 }
}

Following diagram shows where variables created in above program will be stored.

  • Static variables inside method area
  • Instance variables in heap area
  • Local variables in static memory area

So, that's all about method area's inside JVM. Hopefully it helps.
We will continue to remaining components inside JVM, i.e., Execution Engine and JNI (Java Native Interface).

Please provide your inputs in the comments section.
Also, you can follow us at +Java Territory (or here).

Nov 5, 2017

Understanding JVM: Memory Areas in JVM - Part 2

Stack memory

  • It is maintained per thread, i.e., for every thread in Java, JVM will create a separate stack at the time of thread creation.
  • Each and every method call performed by the thread will be stored in stack including local variable also.
  • After completing a method, the corresponding entry from the stack will also be removed. Thus, once all method calls are completed, stack memory will become empty.
  • This empty stack will be destroyed by JVM before terminating the thread.
  • Data stored inside stack is private to corresponding thread only and hence thread-safe.
  • Each entry inside stack is called stack frame/activation record.

Stack Frame structure

Each Stack Frame has 3 parts:
  1. Local Variable Array,
  2. Operand Stack, and
  3. Frame Data
    Local Variable Array
    • It contains all parameters and local variables of the memory.
    • Each slot in the array is of 4 bytes.
    • Type
      • int, float, object -> 1 slot (4 bytes)
      • double, long -> 2 slots (8 bytes)
      • byte, short, char -> converted to int before storing -> 1 slot (4 bytes)
      • boolean -> JVM dependent -> generally 1 slot
    Operand Stack
    • It stores intermediate values.
    • JVM uses operand stack as workspace.
    • Some instructions can push values to operand stack, some instructions can pop values, and some can performance required operations.
    Lets take an example to understand the process. Suppose a program adds 2 values, say 40 and 60.
    JVM instructions will look something like:
    iload - 0 // loads 40
    iload - 1 // loads 60
    iadd // adds 40 and 60
    istore -2 // store the result

    Following is the state if Local Variable Array after first 2 load instructions.
    Local Variable Array

    Values are also loaded in Operand Stack for addition. 
    Operand Stack


    Finally, sum is  pop out from the operand stack and put into local variable array.
    Local Variable Array

    Finally the third component in the frame is Frame Data.

    Frame Data

    • It contains all symbolic references related to the method.
    • Contains references to exception table and will provide corresponding catch block information in case of exception.
    This is all about Stack Memory. Hopefully, it helps.
    Next section will cover the other 2 memory areas, PC registers and native method stack.

    If you like reading our articles, do follow at +Java Territory / Java Territory.

    Oct 11, 2017

    Understanding JVM: Memory Areas in JVM - Part 1

    Whenever JVM load and run a Java program, it needs memory to store several things like bytecode, objects, variables, etc. Total JVM memory is organized into following:

    • Method Area
    • Heap Area
    • Stack Area
    • PC Registers
    • Native Method Stack

    1. Method Area

    • It is created at the time of JVM startup.
    • .class file's binary information is stored into method area.
    • Static variables are stored in method area.
    • Data inside method area is not thread safe.
    • Method area is not contiguous memory.
    • For every JVM, one method area is available.
    • Constant pools of a class are store inside method.

    2. Heap Area

    • There is one heap area per JVM.
    • Like method area, it is also created at the time of JVM startup.
    • Need not be contiguous memory.
    • Objects and corresponding instance variables are stored in the heap area.
    • Every array in Java is object only, hence arrays will also be stored in heap area.
    • Heap area can be accessed by multiple threads, and hence data in heap area is not thread safe.
    Program to Display heap memory statistics
    Heap memory statistics can be captured using Runtime instance. Runtime class is present in java.lang package. It is a singleton class.
    Following code snippet demonstrate how Runtime object can be obtained and used to get heap statistics:

    package com.javaterritory;
    
    public class MemoryTest {
    
     public static void main(String[] args) {
      Runtime r = Runtime.getRuntime(); // get instance of Runtime
      System.out.println("Max memory: " + r.maxMemory()); // prints memory (number of bytes) allocaed to JVM
      System.out.println("Total memory: " + r.totalMemory()); // prints initial memory (in bytes) allocated to JVM
      System.out.println("Free memory: " + r.freeMemory()); // prints the free memory 
     }
    }
    

    Following were the results when I executed it on my machine:

    Max memory: 3797417984
    Total memory: 257425408
    Free memory: 254741016
    

    How to set maximum and minimum heap size
    Following JVM arguments can be used to configuring heap size;
    -Xmx 512m : to set maximum heap size to 512 mb
    -Xms 64m : to set initial heap size to 64 mb

    This is it for Method and Heap area. Next section will cover the stack memory area.
    If you like reading our article, connect with us at +Java Territory  / Java territory to stay updated.

    String intern method - Java 6, 7 and 8

    This article will describe how String.intern method was implemented in Java 6 and what changes were made in it in Java 7 and Java 8.

    String pooling

    String pooling (aka string canonicalisation) is a process of replacing several String objects with equal value but different identity with a single shared String object. You can achieve this goal by keeping your own Map<String, String> (with possibly soft or weak references depending on your requirements) and using map values as canonicalised values. Or you can use String.intern()method which is provided to you by JDK.
    At times of Java 6 using String.intern() was forbidden by many standards due to a high possibility to get an OutOfMemoryException if pooling went out of control. Oracle Java 7 implementation of string pooling was changed considerably. You can look for details at http://bugs.sun.com/view_bug.do?bug_id=6962931 and http://bugs.sun.com/view_bug.do?bug_id=6962930.

    String.intern() in Java 6

    In those good old days all interned strings were stored in the PermGen – the fixed size part of heap mainly used for storing loaded classes and string pool. Besides explicitly interned strings, PermGen string pool also contained all literal strings earlier used in your program (the important word here is used – if a class or method was never loaded/called, any constants defined in it will not be loaded).
    The biggest issue with such string pool in Java 6 was its location – the PermGen. PermGen has a fixed size and can not be expanded at runtime. You can set it using -XX:MaxPermSize=N option. As far as I know, the default PermGen size varies between 32M and 96M depending on the platform. You can increase its size, but its size will still be fixed. Such limitation required very careful usage of String.intern – you’d better not intern any uncontrolled user input using this method. That’s why string pooling at times of Java 6 was mostly implemented in the manually managed maps.

    String.intern() in Java 7

    Oracle engineers made an extremely important change to the string pooling logic in Java 7 – the string pool was relocated to the heap. It means that you are no longer limited by a separate fixed size memory area. All strings are now located in the heap, as most of other ordinary objects, which allows you to manage only the heap size while tuning your application. Technically, this alone could be a sufficient reason to reconsider using String.intern() in your Java 7 programs. But there are other reasons.

    String pool values are garbage collected
    Yes, all strings in the JVM string pool are eligible for garbage collection if there are no references to them from your program roots. It applies to all discussed versions of Java. It means that if your interned string went out of scope and there are no other references to it – it will be garbage collected from the JVM string pool.
    Being eligible for garbage collection and residing in the heap, a JVM string pool seems to be a right place for all your strings, isn’t it? In theory it is true – non-used strings will be garbage collected from the pool, used strings will allow you to save memory in case then you get an equal string from the input. Seems to be a perfect memory saving strategy? Nearly so. You must know how the string pool is implemented before making any decisions.

    JVM string pool implementation in Java 6, 7 and 8

    The string pool is implemented as a fixed capacity hash map with each bucket containing a list of strings with the same hash code. Some implementation details could be obtained from the following Java bug report: http://bugs.sun.com/view_bug.do?bug_id=6962930.
    The default pool size is 1009 (it is present in the source code of the above mentioned bug report, increased in Java7u40). It was a constant in the early versions of Java 6 and became configurable between Java6u30 and Java6u41. It is configurable in Java 7 from the beginning (at least it is configurable in Java7u02). You need to specify -XX:StringTableSize=N, where N is the string pool map size. Ensure it is a prime number for the better performance.
    This parameter will not help you a lot in Java 6, because you are still limited by a fixed size PermGen size. The further discussion will exclude Java 6.

    Java7 (until Java7u40)

    In Java 7, on the other hand, you are limited only by a much higher heap size. It means that you can set the string pool size to a rather high value in advance (this value depends on your application requirements). As a rule, one starts worrying about the memory consumption when the memory data set size grows to at least several hundred megabytes. In this situation, allocating 8-16 MB for a string pool with one million entries seems to be a reasonable trade off (do not use 1,000,000 as a -XX:StringTableSize value – it is not prime; use 1,000,003 instead).
    You must set a higher -XX:StringTableSize value (compared to the default 1009) if you intend to actively use String.intern() – otherwise this method performance will soon degrade to a linked list performance.
    I have not noticed a dependency from a string length to a time to intern a string for string lengths under 100 characters (I feel that duplicates of even 50 character long strings are rather unlikely in the real world data, so 100 chars seems to be a good test limit for me).
    Here is an extract from the test application log with the default pool size: time to intern 10.000 strings (second number) after a given number of strings was already interned (first number);Integer.toString( i ), where i between 0 and 999,999 were interned:
    0; time = 0.0 sec
    50000; time = 0.03 sec
    100000; time = 0.073 sec
    150000; time = 0.13 sec
    200000; time = 0.196 sec
    250000; time = 0.279 sec
    300000; time = 0.376 sec
    350000; time = 0.471 sec
    400000; time = 0.574 sec
    450000; time = 0.666 sec
    500000; time = 0.755 sec
    550000; time = 0.854 sec
    600000; time = 0.916 sec
    650000; time = 1.006 sec
    700000; time = 1.095 sec
    750000; time = 1.273 sec
    800000; time = 1.248 sec
    850000; time = 1.446 sec
    900000; time = 1.585 sec
    950000; time = 1.635 sec
    1000000; time = 1.913 sec
    These test results were obtained on Core i5-3317U@1.7Ghz CPU. As you can see, they grow linearly and I was able to intern only approximately 5,000 strings per second when the JVM string pool size contained one million strings. It is unacceptably slow for most of applications having to handle a large amount of data in memory.

    Oct 7, 2017

    Understanding JVM: How Class Loader works?

    Previous article was related to the types of class loader. I this post, we will see how these types works to load a class file. 

    Class loader sub system follows Delegation Hierarchy algorithm for loading any class file. It is explained below.

    Step 1: When request comes for a class file, JVM first look if is already loaded or not.
    Step 2: If already loaded, JVM finds it in the memory area.
    Step 3: If not, it requests class loader sub system to load the requested class file.
    Step 4: Class loader sub system first sends the request to Application class loader.
    Step 5: Application class loader delegates the request to Extension class loader.
    Step 6: Extension class loader delegates it further to Bootstrap class loader.
    Step 7: Bootstrap class loader searches class file in the bootstrap class path. If found, it is loaded.
    Step 8: If not found, Bootstrap class loader delegates request to Extension class loader.
    Step 9: Extension class loader searches it in the extension class path. If found, it gets loaded.
    Step 10: If not found, request is again delegated to the  Application class loader which searches class file in the application class path and loads if found.
    Step 11: If still not found, ClassNotFoundExcetpion is thrown.

    Thus, Bootstrap class loader has the highest priority while Application class loader has the lowest. If same name class file is present in more than one class paths, higher priority class loader will be given the preference.

    In next article, we will talk about how can create a custom class loader and what is the need for it.
    If you like reading our articles, do like and share with other peoples. You can also connect with us at +Java Territory or Java Territory to stay updated.