Java Garbage Collection Distilled

Serial, Parallel, Concurrent, CMS, G1, Young Gen, New Gen, Old Gen, Perm Gen, Eden, Tenured, Survivor Spaces, Safepoints, and the hundreds of JVM start-up flags. Does this all baffle you when trying to tune the garbage collector while trying to get the required throughput and latency from your Java application? If it does then don’t worry, you are not alone. Documentation describing garbage collection feels like man pages for an aircraft. Every knob and dial is detailed and explained but nowhere can you find a guide on how to fly. This article will attempt to explain the tradeoffs when choosing and tuning garbage collection algorithms for a particular workload.

The focus will be on Oracle Hotspot JVM and OpenJDK collectors as those are the ones in most common usage. Towards the end other commercial JVMs will be discussed to illustrate alternatives.

The Tradeoffs

Wise folk keep telling us, “You don’t get something for nothing”. When we get something we usually have to give up something in return. When it comes to garbage collection we play with 3 major variables that set targets for the collectors:

  1. Throughput: The amount of work done by an application as a ratio of time spent in GC. Target throughput with ‑XX:GCTimeRatio=99; 99 is the default equating to 1% GC time.
  2. Latency: The time taken by systems in responding to events which is impacted by pauses introduced by garbage collection. Target latency for GC pauses with‑XX:MaxGCPauseMillis=<n>.
  3. Memory: The amount of memory our systems use to store state, which is often copied and moved around when being managed. The set of active objects retained by the application at any point in time is known as the Live Set. Maximum heap size –Xmx<n> is a tuning parameter for setting the heap size available to an application.

Note: Often Hotspot cannot achieve these targets and will silently continue without warning, having missed its target by a great margin.

Latency is a distribution across events. It may be acceptable to have an increased average latency to reduce the worse-case latency, or make it less frequent. We should not interpret the term “real-time” to mean the lowest possible latency; rather it refers to having a deterministic latency regardless of throughput.

For some application workloads, throughput is the most important target. An example would be a long running batch-processing job; it does not matter if a batch job is occasionally paused for a few seconds while garbage collection takes place, as long as the overall job can be completed sooner.

For virtually all other workloads, from human facing interactive applications to financial trading systems, if a system goes unresponsive for anything more than a few seconds or milliseconds, it can spell disaster. In financial trading it is often worthwhile to trade off some throughput in return for consistent latency. We may also have applications that are limited by the amount of physical memory available and have to maintain a footprint, in which case we have to give up performance on both latency and throughput fronts.

Tradeoffs often play out as follows:

  • To a large extent the cost of garbage collection, as an amortized cost, can be reduced by providing the garbage collection algorithms with more memory.
  • The observed worst-case latency-inducing pauses due to garbage collecting can be reduced by containing the live set and keeping the heap size small.
  • The frequency with which pauses occur can be reduced by managing the heap and generation sizes, and by controlling the application’s object allocation rate.
  • The frequency of large pauses can be reduced by concurrently running the GC with the application, sometimes at the expense of throughput.

Object Lifetimes

Garbage collection algorithms are often optimized with the expectation that most objects live for a very short period of time, while relatively few live for very long. In most applications, objects that live for a significant period of time tend to constitute a very small percentage of objects allocated over time. In garbage collection theory this observed behavior is often know as “infant mortality” or the “weak generational hypothesis”. For example, loop Iterators are mostly short lived whereas static Strings are effectively immortal.

Experimentation has shown that generational garbage collectors can usually support an order-of-magnitude greater throughput than non-generational collectors do, and thus are almost ubiquitously used in server JVMs. By separating the generations of objects, we know that a region of newly allocated objects is likely to be very sparse for live objects. Therefore a collector that scavenges for the few live objects in this new region and copies them to another region for older objects can be very efficient. Hotspot garbage collectors record the age of an object in terms of the number of GC cycles survived.

Note: If your application consistently generates a lot of objects that live for a fairly long time then expect your application to be spending a significant portion of its time garbage collecting, and expect to be spending a significant portion of your time tuning the Hotspot garbage collectors. This is due to the reduced GC efficiency that happens when the generational “filter” is less effective, and resulting cost of collecting the longer living generations more often. Older generations are less sparse, and as a result the efficiency of older generation collection algorithms tends to be much lower. Generational garbage collectors tend to operate in two distinct collection cycles: Minor collections, where short-lived objects are collected, and the less frequent Major collections, where the older regions are collected.

Stop-The-World Events

The pauses that applications suffer during garbage collection are due to what are known as stop-the-world events. For garbage collectors to operate it is necessary, for practical engineering reasons, to periodically stop the running application so that memory can be managed. Depending on the algorithms, different collectors will stop-the-world at specific points of execution for varying durations of time. To bring an application to a total stop it is necessary to pause all the running threads. Garbage collectors do this by signaling the threads to stop when they come to a “safepoint”, which is a point during program execution at which all GC roots are known and all heap object contents are consistent. Depending on what a thread is doing it may take some time to reach a safepoint. Safepoint checks are normally performed on method returns and loop back edges, but can be optimized away in some places making them more dynamically rare. For example, if a thread is copying a large array, cloning a large object, or executing a monotonic counted loop with a finite bound, it may be many milliseconds before a safepoint is reached. Time to safepoint is an important consideration in low-latency applications. This time can be surfaced by enabling
the ‑XX:+PrintGCApplicationStoppedTime flag in addition to the other GC flags.

Note: For applications with a large number of running threads, when a stop-the-world event occurs a system will undergo significant scheduling pressure as the threads resume when released from safepoints. Therefore algorithms with less reliance on stop-the-world events can potentially be more efficient.

Heap Organization in Hotspot

To understand how the different collectors operate it is best to explore how the Java heap is organized to support generational collectors.

Eden is the region where most objects are initially allocated. The survivor spaces are a temporary store for objects that have survived a collection of the Eden space. Survivor space usage will be described when minor collections are discussed. Collectively Eden and the survivorspaces are known as the “young” or “new” generation.

Objects that live long enough are eventually promoted to the tenured space.

The perm generation is where the runtime stores objects it “knows” to be effectively immortal, such as Classes and static Strings. Unfortunately the common use of class loading on an ongoing basis in many applications makes the motivating assumption behind the permgeneration (that classes are immortal) wrong. In Java 7 interned Strings were moved frompermgen to tenured, and from Java 8 the perm generation is no more and will not be discussed in this article. Most other commercial collectors do not use a separate perm space and tend to treat all long living objects as tenured.

Note: The Virtual spaces allow the collectors to adjust the size of regions to meet throughput and latency targets. Collectors keep statistics for each collection phase and adjust the region sizes accordingly in an attempt to reach the targets.

Object Allocation

To avoid contention each thread is assigned a Thread Local Allocation Buffer (TLAB) from which it allocates objects. Using TLABs allows object allocation to scale with number of threads by avoiding contention on a single memory resource. Object allocation via a TLAB is a very cheap operation; it simply bumps a pointer for the object size which takes roughly 10 instructions on most platforms. Heap memory allocation for Java is even cheaper than using malloc from the C runtime.

Note: Whereas individual object allocation is very cheap, the rate at which minor collection must occur is directly proportional to the rate of object allocation.

When a TLAB is exhausted a thread simply requests a new one from the Eden space. WhenEden has been filled a minor collection commences.

Large objects (-XX:PretenureSizeThreshold=n) may fail to be accommodated in the younggeneration and thus have to be allocated in the old generation, e.g. a large array. If the threshold is set below TLAB size then objects that fit in the TLAB will not be created in the oldgeneration. The new G1 collector handles large objects differently and will be discussed later in its own section.

Minor Collections

minor collection is triggered when Eden becomes full. This is done by copying all the live objects in the new generation to either a survivor space or the tenured space as appropriate. Copying to the tenured space is known as promotion or tenuring. Promotion occurs for objects that are sufficiently old (– XX:MaxTenuringThreshold), or when the survivor space overflows.

Live objects are objects that are reachable by the application; any other objects cannot be reached and can therefore be considered dead. In a minor collection, the copying of live objects is performed by first following what are known as GC Roots, and iteratively copying anything reachable to the survivor space. GC Roots normally include references from application and JVM-internal static fields, and from thread stack-frames, all of which effectively point to the application’s reachable object graphs.

In generational collection, the GC Roots for the new generation’s reachable object graph also include any references from the old generation to the new generation. These references must also be processed to make sure all reachable objects in the new generation survive the minorcollection. Identifying these cross-generational references is achieved by use of a “card table”. The Hotspot card table is an array of bytes in which each byte is used to track the potential existence of cross-generational references in a corresponding 512 byte region of the oldgeneration. As references are stored to the heap, “store barrier” code will mark cards to indicate that a potential reference from the old generation to the new generation may exist in the associated 512 byte heap region. At collection time, the card table is used to scan for such cross-generational references, which effectively represent additional GC Roots into the newgeneration. Therefore a significant fixed cost of minor collections is directly proportional to the size of the old generation.

There are two survivor spaces in the Hotspot new generation, which alternate in their “to-space” and “from-space” roles. At the beginning of a minor collection, the “to-space” survivor space is always empty, and acts as a target copy area for the minor collection. The previous minorcollection’s target survivor space is part of the “from-space”, which also includes Eden, where live objects that need to be copied may be found.

The cost of a minor GC collection is usually dominated by the cost of copying objects to thesurvivor and tenured spaces. Objects that do not survive a minor collection are effectively free to be dealt with. The work done during a minor collection is directly proportional to the number of live objects found, and not to the size of the new generation. The total time spent doing minorcollections can be almost be halved each time the Eden size is doubled. Memory can therefore be traded for throughput. A doubling of Eden size will result in an increase in collection time per-collection cycle, but this is relatively small if both the number of objects being promoted and size of the old generation is constant.

Note: In Hotspot minor collections are stop-the-world events. This is rapidly becoming a major issue as our heaps get larger with more live objects. We are already starting to see the need for concurrent collection of the young generation to reach pause-time targets.

Major Collections

Major collections collect the old generation so that objects can be promoted from the younggeneration. In most applications, the vast majority of program state ends up in the oldgeneration. The greatest variety of GC algorithms exists for the old generation. Some will compact the whole space when it fills, whereas others will collect concurrently with the application to try and prevent it from filling up.

The old generation collector will try to predict when it needs to collect to avoid a promotion failure from the young generation. The collectors track a fill threshold for the old generation and begin collection when this threshold is passed. If this threshold is not sufficient to meet promotion requirements then a “FullGC” is triggered. A FullGC involves promoting all live objects from the young generations followed by a collection and compaction of the old generation. Promotion failure is a very expensive operation as state and promoted objects from this cycle must be unwound so the FullGC event can occur.

Note: To avoid promotion failure you will need to tune the padding that the old generation allows to accommodate promotions (‑XX:PromotedPadding=<n>).

Note: When the Heap needs to grow a FullGC is triggered. These heap-resizing FullGCs can be avoided by setting –Xms and –Xmx to the same value.

Other than a FullGC, a compaction of the old generation is likely to be the largest stop-the-world pause an application will experience. The time for this compaction tends to grow linearly with the number of live objects in the tenured space.

The rate at which the tenured space fills up can sometimes be reduced by increasing the size of the survivor spaces and the age of objects before being promoted to the tenured generation. However, increasing the size of the survivor spaces and object age in Minor collections (–XX:MaxTenuringThreshold) before promotion can also increase the cost and pause times in theminor collections due to the increased copy cost between survivor spaces on minor collections.

Serial Collector

The Serial collector (-XX:+UseSerialGC) is the simplest collector and is a good option for single processor systems. It also has the smallest footprint of any collector. It uses a single thread for both minor and major collections. Objects are allocated in the tenured space using a simple bump the pointer algorithm. Major collections are triggered when the tenured space is full.

Parallel Collector

The Parallel collector comes in two forms. The Parallel Collector (‑XX:+UseParallelGC) which uses multiple threads to perform minor collections of the Young generation and a single thread for major collections on the old generation. The Parallel Old Collector (‑XX:+UseParallelOldGC) , the default since Java 7u4, uses multiple threads for minor collections and multiple threads formajor collections. Objects are allocated in the tenured space using a simple bump the pointer algorithm. Major collections are triggered when the tenured space is full.

On multi-processor systems the Parallel Old collector will give the greatest throughput of any collector. It has no impact on a running application until a collection occurs, and then will collect in parallel using multiple threads using the most efficient algorithm. This makes the Parallel Old collector very suitable for batch applications.

The cost of collecting the old generations is affected by the number of objects to retain to a greater extent than by the size of the heap. Therefore the efficiency of the Parallel Old collector can be increased to achieve greater throughput by providing more memory and accepting larger, but fewer, collection pauses.

Expect the fastest Minor collections with this collector because the promotion to tenured space is a simple bump the pointer and copy operation.

For server applications the Parallel Old collector should be the first port-of-call. However if themajor collection pauses are more than your application can tolerate then you need to consider employing a concurrent collector that collects the tenured objects concurrently while the application is running.

Note: Expect pauses in the order of one to five seconds per GB of live data on modern hardware while the old generation is compacted.

Concurrent Mark Sweep (CMS) Collector

The CMS (-XX:+UseConcMarkSweepGC) collector runs in the Old generation collecting tenured objects that are no longer reachable during a major collection. It runs concurrently with the application with the goal of keeping sufficient free space in the old generation so that a promotion failure from the young generation does not occur.

Promotion failure will trigger a FullGC. CMS follows a multistep process:

  1. Initial Mark <stop-the-world>: Find GC Roots.
  2. Concurrent Mark: Mark all reachable objects from the GC Roots.
  3. Concurrent Pre-clean: Check for object references that have been updated and objects that have been promoted during the concurrent mark phase by remarking.
  4. Re-mark <stop-the-world>: Capture object references that have been updated since the Pre-clean stage.
  5. Concurrent Sweep: Update the free-lists by reclaiming memory occupied by dead objects.
  6. Concurrent Reset: Reset data structures for next run.

As tenured objects become unreachable, the space is reclaimed by CMS and put on free-lists. When promotion occurs, the free-lists must be searched for a suitable sized hole for the promoted object. This increases the cost of promotion and thus increases the cost of the Minor collections compared to the Parallel Collector.

Note: CMS is not a compacting collector, which over time can result in old generation fragmentation. Object promotion can fail because a large object may not fit in the available holes in the old generation. When this happens a “promotion failed” message is logged and a FullGC is triggered to compact the live tenured objects. For such compaction-driven FullGCs, expect pauses to worse than major collections using the Parallel Old collector because CMS uses a single thread for compaction.

CMS is mostly concurrent with the application, which has a number of implications. First, CPU time is taken by the collector, thus reducing the CPU available to the application. The amount of time required by CMS grows linearly with the amount of object promotion to the tenured space. Second, for some phases of the concurrent GC cycle, all application threads have to be brought to a safepoint for marking GC Roots and performing a parallel re-mark to check for mutation.

Note: If an application sees significant mutation of tenured objects then the re-mark phase can be significant, at the extremes it may take longer than a full compaction with the Parallel Old collector.

CMS makes FullGC a less frequent event at the expense of reduced throughput, more expensive minor collections, and greater footprint. The reduction in throughput can be anything from 10%-40% compared to the Parallel collector, depending on promotion rate. CMS also requires a 20% greater footprint to accommodate additional data structures and “floating garbage” that can be missed during the concurrent marking that gets carried over to the next cycle.

High promotion rates and resulting fragmentation can sometimes be reduced by increasing the size of both the young and old generation spaces.

Note: CMS can suffer “concurrent mode failures”, which can be seen in the logs, when it fails to collect at a sufficient rate to keep up with promotion. This can be caused when the collection commences too late, which can be addressed by tuning. But it can also occur when the collection rate cannot keep up with the high promotion rate or with the high object mutation rate of some applications. If the promotion rate or mutation rate of the application is too high then your application might require some changes to reduce the promotion pressure. Adding more memory to such a system can sometimes make the situation worse, as CMS would then have more memory to scan.

Garbage First (G1) Collector

G1 (-XX:+UseG1GC) is a new collector introduced in Java 6 and now officially supported in Java 7. It is a partially concurrent collecting algorithm that also tries to compact the tenured space in smaller incremental stop-the-world pauses to try and minimize the FullGC events that plague CMS because of fragmentation. G1 is a generational collector that organizes the heap differently from the other collectors by dividing it into fixed size regions of variable purpose, rather than contiguous regions for the same purpose.

G1 takes the approach of concurrently marking regions to track references between regions, and to focus collection on the regions with the most free space. These regions are then collected in stop-the-world pause increments by evacuating the live objects to an empty region, thus compacting in the process. Objects larger than 50% of a region are allocated in humongous regions, that are a multiple of region size. Allocation and collection of humongous objects can be very costly under G1, and to date has had little or no optimization effort applied.

The challenge with any compacting collector is not the moving of objects but the updating of references to those objects. If an object is referenced from many regions then updating those references can take significantly longer than moving the object. G1 tracks which objects in a region have references from other regions via the “Remembered Sets”. If the Remembered Sets become large then G1 can significantly slow down. When evacuating objects from one region to another, the length of the associated stop-the-world event tends to be proportional to the number of regions with references that need to be scanned and potentially patched.

Maintaining the Remembered Sets increases the cost of minor collections resulting in pauses greater than those seen with Parallel Old or CMS collectors for Minor collections.

G1 is target driven on latency –XX:MaxGCPauseMillis=<n>, default value = 200ms. The target will influence the amount of work done on each cycle on a best-efforts only basis. Setting targets in tens of milliseconds is mostly futile, and as of this writing targeting tens of milliseconds has not been a focus of G1.

G1 is a good general-purpose collector for larger heaps that have a tendency to become fragmented when an application can tolerate pauses in the 0.5-1.0 second range for incremental compactions. G1 tends to reduce the frequency of the worst-case pauses seen by CMS because of fragmentation at the cost of extended minor collections and incremental compactions of the old generation. Most pauses end up being constrained to regional rather than full heap compactions.

Like CMS, G1 can also fail to keep up with promotion rates, and will fall back to a stop-the-world FullGC. Just like CMS has “concurrent mode failure”, G1 can suffer an evacuation failure, seen in the logs as “to-space overflow”. This occurs when there are no free regions into which objects can be evacuated, which is similar to a promotion failure. If this occurs, try using a larger heap and more marking threads, but in some cases application changes may be necessary to reduce allocation rates.

A challenging problem for G1 is dealing with popular objects and regions. Incremental stop-the-world compaction works well when regions have live objects that are not heavily referenced from other regions. If an object or region is popular then the Remembered Set will be large, and G1 will try to avoid collecting those objects. Eventually it can have no choice, which results in very frequent mid-length pauses as the heap gets compacted.

Alternative Concurrent Collectors

CMS and G1 are often called mostly concurrent collectors. When you look at the total work performed it is clear that the young generation, promotion and even much of the old generation work is not concurrent at all. CMS is mostly concurrent for the old generation; G1 is much more of a stop-the-world incremental collector. Both CMS and G1 have significant and regularly occurring stop-the-world events, and worst-case scenarios that often make them unsuitable for strict low-latency applications, such a financial trading or reactive user interfaces.

Alternative collectors are available such as Oracle JRockit Real Time, IBM Websphere Real Time, and Azul Zing. The JRockit and Websphere collectors have latency advantages in most cases over CMS and G1 but often see throughput limitations and still suffer significant stop-the-world events. Zing is the only Java collector know to this author that can be truly concurrent for collection and compaction while maintaining a high-throughput rate for all generations. Zing does have some sub-millisecond stop-the-world events but these are for phase shifts in the collection cycle that are not related to live set size.

JRockit RT can achieve typical pause times in the tens of milliseconds for high allocation rates at contained heap sizes but occasionally has to fail back to full compaction pauses. Websphere RT can achieve single-digit millisecond pause times via constrained allocation rates and live set sizes. Zing can achieve sub-millisecond pauses with high allocation rates by being concurrent for all phases, including during minor collections. Zing is able to maintain this consistent behavior regardless of heap size, allowing the user to apply large heap sizes as needed for keeping up with application throughput or object model state needs, without fear of increased pause times.

For all the concurrent collectors targeting latency you have to give up some throughput and gain footprint. Depending on the efficiency of the concurrent collector you may give up a little throughput but you are always adding significant footprint. If truly concurrent, with few stop-the-world events, then more CPU cores are needed to enable the concurrent operation and maintain throughput.

Note: All the concurrent collectors tend to function more efficiently when sufficient space is allocated. As a starting point rule of thumb, you should budget a heap of at least two to three times the size of the live set for efficient operation. However, space requirements for maintaining concurrent operation grows with application throughput, and the associated allocation and promotion rates. So for higher throughput applications a higher heap-size to live set ratio may be warranted. Given the huge memory spaces available to today’s systems footprint is seldom an issue on the server side.

Garbage Collection Monitoring & Tuning

To understand how your application and garbage collector are behaving, start your JVM with at least the following settings:


Then load the logs into a tool like Chewiebug for analysis.

To see the dynamic nature of GC, launch JVisualVM and install the Visual GC plugin. This will enable you to see the GC in action for your application as below.

To get an understanding of your applcations’ GC needs, you need representative load tests that can be executed repeatedly. As you get to grips with how each of the collectors work then run your load tests with different configurations as experiments until you reach your throughput and latency targets. It is important to measure latency from the end user perspective. This can be achieved by capturing the response time of every test request in a histogram, and you can read more about that here. If you have latency spikes that are outside your acceptable range, then try and correlate these with the GC logs to determine if GC is the issue. It is possible other issues may be causing latency spikes. Another useful tool to consider is jHiccup which can be used to track pauses within the JVM and across a system as a whole.

If latency spikes are due to GC then invest in tuning CMS or G1 to see if your latency targets can be meet. Sometimes this may not be possible because of high allocation and promotion rates combined with very low-latency requirements. GC tuning can become a highly skilled exercise that often requires application changes to reduce object allocation rates or object lifetimes. If this is the case then a commercial trade-off between time and resource spent on GC tuning and application changes, verses, purchasing one of the commercial concurrent compacting JVMs such as JRockit Real Time or Azul Zing may be required.


source :

Why Multiple Inheritance is Not Supported in Java

In an white paper titled “Java: an Overview” by James Gosling in February 1995 gives an idea on why multiple inheritance is not supported in Java.

JAVA omits many rarely used, poorly understood, confusing features of C++ that in our experience bring more grief than benefit. This primarily consists of operator overloading (although it does have method overloading), multiple inheritance, and extensive automatic coercions.

Who better than Dr. James Gosling is qualified to make a comment on this. This paragraph gives us an overview and he touches this topic of not supporting multiple-inheritance.

Java does not support multiple inheritance

First lets nail this point. This itself is a point of discussion, whether java supports multiple inheritance or not. Some say, it supports using interface. No. There is no support for multiple inheritance in java. If you do not believe my words, read the above paragraph again and those are words of the father of Java.

This story of supporting multiple inheritance using interface is what we developers cooked up. Interface gives flexibility than concrete classes and we have option to implement multiple interface using single class. This is by agreement we are adhering to two blueprints to create a class.

This is trying to get closer to multiple inheritance. What we do is implement multiple interface, here we are not extending (inheriting) anything. The implementing class is the one that is going to add the properties and behavior. It is not getting the implementation free from the parent classes. I would simply say, there is no support for multiple inheritance in java.

Multiple Inheritance

Multiple inheritance is where we inherit the properties and behavior of multiple classes to a single class. C++, Common Lisp, are some popular languages that support multiple inheritance.

Multiple Inheritance

Why Java does not support multiple inheritance?

Now we are sure that there is no support for multiple inheritance in java. But why? This is a design decision taken by the creators of java. The keyword is simplicity and rare use.


I want to share the definition for java given by James Gosling.

JAVA: A simple, object oriented, distributed, interpreted, robust, secure, architecture neutral, portable, high performance, multithreaded, dynamic language.

Look at the beauty of this definition for java. This should be the definition for a modern software language. What is the first characteristic in the language definition? It is simple.

In order to enforce simplicity should be the main reason for omitting multiple inheritance. For instance, we can consider diamond problem of multiple inheritance.

Diamond Problem of Multiple Inheritance

We have two classes B and C inheriting from A. Assume that B and C are overriding an inherited method and they provide their own implementation. Now D inherits from both B and C doing multiple inheritance. D should inherit that overridden method, which overridden method will be used? Will it be from B or C? Here we have an ambiguity.

In C++ there is a possibility to get into this trap though it provides alternates to solve this. In java this can never occur as there is no multiple inheritance. Here even if two interfaces are going to have same method, the implementing class will have only one method and that too will be done by the implementer. Dynamic loading of classes makes the implementation of multiple inheritance difficult.

Rarely Used

We have been using java for long now. How many times have we faced a situation where we are stranded and facing the wall because of the lack of support for multiple inheritance in java? With my personal experience I don’t remember even once. Since it is rarely required, multiple inheritance can be safely omitted considering the complexity it has for implementation. It is not worth the hassle and the path of simplicity is chosen.

Even if it is required it can be substituted with alternate design. So it is possible to live without multiple inheritance without any issues and that is also one reason.

My opinion on this is, omitting support for multiple inheritance in java is not a flaw and it is good for the implementers.


Src :

Dynamic Loading using Java Reflection and Properties.

What is Java Reflection and Properties

In this article I will be explaining how you load classes dynamically using a properties file and Java Reflections. The Properties file are basically a collection of key-value pairs. It is the most commonly used mechanism for storing applications configuration data and settings. Reflection is a feature available in Java used by developers for examining and modifying the run-time behavior of applications running in the JVM.

MyBirds example

Let us start with a very simple problem statement: I should be able to load characters of a particular bird when I specify it’s name. For e.g: When i specify duck, the calling the sound() function should print “quack”;

This is a situation where you need to load a class dynamically based on some data provided by the client or external source. You also want the flexibility to configure classes in a simple properties file and these classes are having similar behavior.

To implement this we will need the following components:

  • – The properties file where you can map keys to your class
  • – An interface which all the classes specified in the properties file will have to implement.
  •, – The classes that implements the interface MyBird.
  • – The factory class that dynamically creates classes

Let us look at the code for each of these. Let us start with



public interface MyBird {
    public String sound();

Now let us see and;

public class Duck implements MyBird {
    public String sound() {
        return "Quack";

public class Eagle implements MyBird {
    public String sound() {
        return "Scream";
} is the class responsible for creating the desirable instance based on the birdType input passed to it.


import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Locale;
import java.util.ResourceBundle;
publicclassMyBirdFactory {
    private static final String MY_BIRDS_CONFIGURATION = "mybirds";
    private static Hashtable<String, String> myBirdsMappings = new Hashtable<String, String>();
    static {
        try {
        } catch (Exception e) {
    public static MyBird getMyBird(String birdType) {
        String className = myBirdsMappings.get(birdType);
        MyBird bird = null;
        try {
            if( className!=null) {
                Class cls = Class.forName(className);
                bird = (MyBird)cls.newInstance();
        } catch (Exception e) {
        return bird;
    private static void loadMyBirdsrMappings() {
        ResourceBundle rb = ResourceBundle.getBundle(MY_BIRDS_CONFIGURATION, Locale.getDefault());
        for (Enumeration e = rb.getKeys(); e.hasMoreElements();) {
            String key = (String) e.nextElement();
            myBirdsMappings.put(key, rb.getString(key));

We can write to test the code.


public class TestCode {

    public static void main(String[] args) {
        if(args.length <=0)
            System.out.println("Please provide input. E.G: duck eagle duck ...");
        else {
            for(String name:args){
                MyBird bird = MyBirdFactory.getMyBird( name );
                if(bird == null){
                    System.out.println("Couldn't find your bird. Please make sure it's entered in");
                } else {
                    System.out.println("The sound of the bird"  + name + " is " + bird.sound() );

Check out the output when you run the code.

C:\Janeve\MyBirds>java -classpath ./ duck duck eagle duck eagle eagle

The sound of the bird duck is Quack
The sound of the bird duck is Quack
The sound of the bird eagle is Scream
The sound of the bird duck is Quack
The sound of the bird eagle is Scream
The sound of the bird eagle is Scream

Source :


Difference between JDK and JRE in Java Platform

Java Platform offers JRE and JDK to run Java programs. JRE stands for Java runtime environment and JDK stands for Java development kit. JRE is meant for normal users, who wants to run Java program in there computer. JRE is normally used to run Java programs downloaded over internet e.g. Java Applets and Java Desktop application built using AWT and Swing. Main difference between JRE and JDK, comes from the fact that they are different tools. JDK is created for Java programmers, and contains tools required for Java programming, e.g. javac for compiling Java source files to .class files. Without JDK, you can not create Javaapplications and programs. By the way JDK comes with it’s own JRE, but when you run Java program using java command, the JRE which comes first in System PATH is used for execution. One of the important thing to know is that, you can not run Java program from your machine if you don’t have either JRE or JDK. You can also consider JDK as super set, which also contains JRE. For a normal user, installing JDK is overkill. They needs JRE only and any browser will assist them for installing JRE, as browser plugin. By the way, beware with any security issue, while installing JRE.  JRE releases sometimes has security flaws which can compromise your computer, that’s the reason recently many browser has by default disabled Java. Any way, in next section we will see some moredifference between JRE and JDK in Java.

Difference between JRE vs JDK in Java

In last post, we have seen Difference between JVM and JIT in Java  and Now we will compare JDK and JRE. Here are some points, which is useful to differentiate JRE from JDK. Remember JRE, meant for Java Runtime Environment and JDK stands for Java Development Kit. If you go  by there name, You can easily see what is difference in JDK and JRE.
1) Main difference between JRE and JDK is that, you can not compile Java program using JRE. Tools required for compiling Java sourcefile to create class files, i.e. javac, comes with JDK installation.
2) As name suggest JRE is for running Java program and developed as browser plugin. In order to run any Java program from browser like Internet Explore, Mozilla Firefox or Google Chrome, you need JRE to be installed in your machine and should be enable on your browser as well.
3) JRE is meant for users, while JDK is meant for programmers. Since Java was sensation during Internet boom of 1990s, where Applet was most popular for its rich offering over internet, JRE was required to run those applet on users machines.
That’s all on difference between JRE and JDK in Java platform. As I said, only JRE is enough to run Java program and JDK is required only if you want to do programming in Java platform. For normal internet users JRE is enough, but beware of security hols comes now and then with different Java releases.

JAVA – Regular Expressions

Java provides the java.util.regex package for pattern matching with regular expressions. Java regular expressions are very similar to the Perl programming language and very easy to learn.

A regular expression is a special sequence of characters that helps you match or find other strings or sets of strings, using a specialized syntax held in a pattern. They can be used to search, edit, or manipulate text and data.

The java.util.regex package primarily consists of the following three classes:

  • Pattern Class: A Pattern object is a compiled representation of a regular expression. The Pattern class provides no public constructors. To create a pattern, you must first invoke one of its public static compile methods, which will then return a Pattern object. These methods accept a regular expression as the first argument.
  • Matcher Class: A Matcher object is the engine that interprets the pattern and performs match operations against an input string. Like the Pattern class, Matcher defines no public constructors. You obtain a Matcher object by invoking the matcher method on a Pattern object.
  • PatternSyntaxException: A PatternSyntaxException object is an unchecked exception that indicates a syntax error in a regular expression pattern.

Capturing Groups:

Capturing groups are a way to treat multiple characters as a single unit. They are created by placing the characters to be grouped inside a set of parentheses. For example, the regular expression (dog) creates a single group containing the letters “d”, “o”, and “g”.

Capturing groups are numbered by counting their opening parentheses from left to right. In the expression ((A)(B(C))), for example, there are four such groups:

  • ((A)(B(C)))
  • (A)
  • (B(C))
  • (C)

To find out how many groups are present in the expression, call the groupCount method on a matcher object. The groupCount method returns an int showing the number of capturing groups present in the matcher’s pattern.

There is also a special group, group 0, which always represents the entire expression. This group is not included in the total reported by groupCount.


Following example illustrate how to find a digit string from the given alphanumeric string:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches
    public static void main( String args[] ){

      // String to be scanned to find the pattern.
      String line = "This order was places for QT3000! OK?";
      String pattern = "(.*)(\\d+)(.*)";

      // Create a Pattern object
      Pattern r = Pattern.compile(pattern);

      // Now create matcher object.
      Matcher m = r.matcher(line);
      if (m.find( )) {
         System.out.println("Found value: " + );
         System.out.println("Found value: " + );
         System.out.println("Found value: " + );
      } else {
         System.out.println("NO MATCH");

This would produce following result:

Found value: This order was places for QT3000! OK?
Found value: This order was places for QT300
Found value: 0

Regular Expression Syntax:

Here is the table listing down all the regular expression metacharacter syntax available in Java:

Subexpression Matches
^ Matches beginning of line.
$ Matches end of line.
. Matches any single character except newline. Using m option allows it to match newline as well.
[…] Matches any single character in brackets.
[^…] Matches any single character not in brackets
\A Beginning of entire string
\z End of entire string
\Z End of entire string except allowable final line terminator.
re* Matches 0 or more occurrences of preceding expression.
re+ Matches 1 or more of the previous thing
re? Matches 0 or 1 occurrence of preceding expression.
re{ n} Matches exactly n number of occurrences of preceding expression.
re{ n,} Matches n or more occurrences of preceding expression.
re{ n, m} Matches at least n and at most m occurrences of preceding expression.
a| b Matches either a or b.
(re) Groups regular expressions and remembers matched text.
(?: re) Groups regular expressions without remembering matched text.
(?> re) Matches independent pattern without backtracking.
\w Matches word characters.
\W Matches nonword characters.
\s Matches whitespace. Equivalent to [\t\n\r\f].
\S Matches nonwhitespace.
\d Matches digits. Equivalent to [0-9].
\D Matches nondigits.
\A Matches beginning of string.
\Z Matches end of string. If a newline exists, it matches just before newline.
\z Matches end of string.
\G Matches point where last match finished.
\n Back-reference to capture group number “n”
\b Matches word boundaries when outside brackets. Matches backspace (0x08) when inside brackets.
\B Matches nonword boundaries.
\n, \t, etc. Matches newlines, carriage returns, tabs, etc.
\Q Escape (quote) all characters up to \E
\E Ends quoting begun with \Q

Methods of the Matcher Class:

Here is the lists of useful instance methods:

Index Methods:

Index methods provide useful index values that show precisely where the match was found in the input string:

SN Methods with Description
1 public int start() 
Returns the start index of the previous match.
2 public int start(int group)
Returns the start index of the subsequence captured by the given group during the previous match operation.
3 public int end()
Returns the offset after the last character matched.
4 public int end(int group)
Returns the offset after the last character of the subsequence captured by the given group during the previous match operation.

Study Methods:

Study methods review the input string and return a boolean indicating whether or not the pattern is found:

SN Methods with Description
1 public boolean lookingAt() 
Attempts to match the input sequence, starting at the beginning of the region, against the pattern.
2 public boolean find() 
Attempts to find the next subsequence of the input sequence that matches the pattern.
3 public boolean find(int start
Resets this matcher and then attempts to find the next subsequence of the input sequence that matches the pattern, starting at the specified index.
4 public boolean matches() 
Attempts to match the entire region against the pattern.

Replacement Methods:

Replacement methods are useful methods for replacing text in an input string:

SN Methods with Description
1 public Matcher appendReplacement(StringBuffer sb, String replacement)
Implements a non-terminal append-and-replace step.
2 public StringBuffer appendTail(StringBuffer sb)
Implements a terminal append-and-replace step.
3 public String replaceAll(String replacement) 
Replaces every subsequence of the input sequence that matches the pattern with the given replacement string.
4 public String replaceFirst(String replacement)
Replaces the first subsequence of the input sequence that matches the pattern with the given replacement string.
5 public static String quoteReplacement(String s)
Returns a literal replacement String for the specified String. This method produces a String that will work as a literal replacement s in the appendReplacement method of the Matcher class.

The start and end Methods:

Following is the example that counts the number of times the word “cats” appears in the input string:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches
    private static final String REGEX = "\\bcat\\b";
    private static final String INPUT =
                                    "cat cat cat cattie cat";

    public static void main( String args[] ){
       Pattern p = Pattern.compile(REGEX);
       Matcher m = p.matcher(INPUT); // get a matcher object
       int count = 0;

       while(m.find()) {
         System.out.println("Match number "+count);
         System.out.println("start(): "+m.start());
         System.out.println("end(): "+m.end());

This would produce following result:

Match number 1
start(): 0
end(): 3
Match number 2
start(): 4
end(): 7
Match number 3
start(): 8
end(): 11
Match number 4
start(): 19
end(): 22

You can see that this example uses word boundaries to ensure that the letters “c” “a” “t” are not merely a substring in a longer word. It also gives some useful information about where in the input string the match has occurred.

The start method returns the start index of the subsequence captured by the given group during the previous match operation, and end returns the index of the last character matched, plus one.

The matches and lookingAt Methods:

The matches and lookingAt methods both attempt to match an input sequence against a pattern. The difference, however, is that matches requires the entire input sequence to be matched, while lookingAt does not.

Both methods always start at the beginning of the input string. Here is the example explaining the functionality:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches
    private static final String REGEX = "foo";
    private static final String INPUT = "fooooooooooooooooo";
    private static Pattern pattern;
    private static Matcher matcher;

    public static void main( String args[] ){
       pattern = Pattern.compile(REGEX);
       matcher = pattern.matcher(INPUT);

       System.out.println("Current REGEX is: "+REGEX);
       System.out.println("Current INPUT is: "+INPUT);

       System.out.println("lookingAt(): "+matcher.lookingAt());
       System.out.println("matches(): "+matcher.matches());

This would produce following result:

Current REGEX is: foo
Current INPUT is: fooooooooooooooooo
lookingAt(): true
matches(): false

The replaceFirst and replaceAll Methods:

The replaceFirst and replaceAll methods replace text that matches a given regular expression. As their names indicate, replaceFirst replaces the first occurrence, and replaceAll replaces all occurences.

Here is the example explaining the functionality:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches
    private static String REGEX = "dog";
    private static String INPUT = "The dog says meow. " +
                                    "All dogs say meow.";
    private static String REPLACE = "cat";

    public static void main(String[] args) {
       Pattern p = Pattern.compile(REGEX);
       // get a matcher object
       Matcher m = p.matcher(INPUT); 
       INPUT = m.replaceAll(REPLACE);

This would produce following result:

The cat says meow. All cats say meow.

The appendReplacement and appendTail Methods:

The Matcher class also provides appendReplacement and appendTail methods for text replacement.

Here is the example explaining the functionality:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches
   private static String REGEX = "a*b";
   private static String INPUT = "aabfooaabfooabfoob";
   private static String REPLACE = "-";
   public static void main(String[] args) {
      Pattern p = Pattern.compile(REGEX);
      // get a matcher object
      Matcher m = p.matcher(INPUT);
      StringBuffer sb = new StringBuffer();

This would produce following result:


PatternSyntaxException Class Methods:

A PatternSyntaxException is an unchecked exception that indicates a syntax error in a regular expression pattern. The PatternSyntaxException class provides the following methods to help you determine what went wrong:

SN Methods with Description
1 public String getDescription()
Retrieves the description of the error.
2 public int getIndex() 
Retrieves the error index.
3 public String getPattern() 
Retrieves the erroneous regular expression pattern.
4 public String getMessage() 
Returns a multi-line string containing the description of the syntax error and its index, the erroneous regular expression pattern, and a visual indication of the error index within the pattern.

Source :

The Java™ Tutorials : The Really Big Index

A list of all content pages in the The Java™ Tutorials

Trail: Getting Started

The Java Technology Phenomenon

About the Java Technology
What Can Java Technology Do?
How Will Java Technology Change My Life?

The “Hello World!” Application

“Hello World!” for the NetBeans IDE
“Hello World!” for Microsoft Windows
“Hello World!” for Solaris OS and Linux

A Closer Look at the “Hello World!” Application

Questions and Exercises: Getting Started

Common Problems (and Their Solutions)

Trail: Learning the Java Language

Object-Oriented Programming Concepts

What Is an Object?
What Is a Class?
What Is Inheritance?
What Is an Interface?
What Is a Package?
Questions and Exercises: Object-Oriented Programming Concepts

Language Basics

    Primitive Data Types
    Summary of Variables
    Questions and Exercises: Variables
    Assignment, Arithmetic, and Unary Operators
    Equality, Relational, and Conditional Operators
    Bitwise and Bit Shift Operators
    Summary of Operators
    Questions and Exercises: Operators
Expressions, Statements, and Blocks
Questions and Exercises: Expressions, Statements, and Blocks
Control Flow Statements
    The if-then and if-then-else Statements
    The switch Statement
    The while and do-while Statements
    The for Statement
    Branching Statements
    Summary of Control Flow Statements
    Questions and Exercises: Control Flow Statements

Classes and Objects

    Declaring Classes
    Declaring Member Variables
    Defining Methods
    Providing Constructors for Your Classes
    Passing Information to a Method or a Constructor
    Creating Objects
    Using Objects
More on Classes
    Returning a Value from a Method
    Using the this Keyword
    Controlling Access to Members of a Class
    Understanding Instance and Class Members
    Initializing Fields
    Summary of Creating and Using Classes and Objects
    Questions and Exercises: Classes
    Questions and Exercises: Objects
Nested Classes
    Inner Class Example
    Summary of Nested Classes
    Questions and Exercises: Nested Classes
Enum Types
Questions and Exercises: Enum Types
Questions and Exercises: Annotations

Interfaces and Inheritance

    Defining an Interface
    Implementing an Interface
    Using an Interface as a Type
    Rewriting Interfaces
    Summary of Interfaces
    Questions and Exercises: Interfaces
    Overriding and Hiding Methods
    Hiding Fields
    Using the Keyword super
    Object as a Superclass
    Writing Final Classes and Methods
    Abstract Methods and Classes
    Summary of Inheritance
    Questions and Exercises: Inheritance

Numbers and Strings

    The Numbers Classes
    Formatting Numeric Print Output
    Beyond Basic Arithmetic
    Summary of Numbers
    Questions and Exercises: Numbers
    Converting Between Numbers and Strings
    Manipulating Characters in a String
    Comparing Strings and Portions of Strings
    The StringBuilder Class
    Summary of Characters and Strings
Autoboxing and Unboxing
Questions and Exercises: Characters and Strings

Generics (Updated)

Why Use Generics?
Generic Types
    Raw Types
Generic Methods
Bounded Type Parameters
    Generic Methods and Bounded Type Parameters
Generics, Inheritance, and Subtypes
Type Inference
    Upper Bounded Wildcards
    Unbounded Wildcards
    Lower Bounded Wildcards
    Wildcards and Subtyping
    Wildcard Capture and Helper Methods
    Guidelines for Wildcard Use
Type Erasure
    Erasure of Generic Types
    Erasure of Generic Methods
    Effects of Type Erasure and Bridge Methods
    Non-Reifiable Types
Restrictions on Generics
Questions and Exercises: Generics


Creating and Using Packages
    Creating a Package
    Naming a Package
    Using Package Members
    Managing Source and Class Files
    Summary of Creating and Using Packages
    Questions and Exercises: Creating and Using Packages

Trail: Essential Classes


What Is an Exception?
The Catch or Specify Requirement
Catching and Handling Exceptions
    The try Block
    The catch Blocks
    The finally Block
    The try-with-resources Statement
    Putting It All Together
Specifying the Exceptions Thrown by a Method
How to Throw Exceptions
    Chained Exceptions
    Creating Exception Classes
Unchecked Exceptions — The Controversy
Advantages of Exceptions
Questions and Exercises

Basic I/O

I/O Streams
    Byte Streams
    Character Streams
    Buffered Streams
    Scanning and Formatting
    I/O from the Command Line
    Data Streams
    Object Streams
File I/O (Featuring NIO.2)
    What Is a Path? (And Other File System Facts)
    The Path Class
        Path Operations
    File Operations
    Checking a File or Directory
    Deleting a File or Directory
    Copying a File or Directory
    Moving a File or Directory
    Managing Metadata (File and File Store Attributes)
    Reading, Writing, and Creating Files
    Random Access Files
    Creating and Reading Directories
    Links, Symbolic or Otherwise
    Walking the File Tree
    Finding Files
    Watching a Directory for Changes
    Other Useful Methods
    Legacy File I/O Code
Questions and Exercises: Basic I/O


Processes and Threads
Thread Objects
    Defining and Starting a Thread
    Pausing Execution with Sleep
    The SimpleThreads Example
    Thread Interference
    Memory Consistency Errors
    Synchronized Methods
    Intrinsic Locks and Synchronization
    Atomic Access
    Starvation and Livelock
Guarded Blocks
Immutable Objects
    A Synchronized Class Example
    A Strategy for Defining Immutable Objects
High Level Concurrency Objects
    Lock Objects
        Executor Interfaces
        Thread Pools
    Concurrent Collections
    Atomic Variables
    Concurrent Random Numbers
For Further Reading
Questions and Exercises: Concurrency

The Platform Environment

Configuration Utilities
    Command-Line Arguments
    Environment Variables
    Other Configuration Utilities
System Utilities
    Command-Line I/O Objects
    System Properties
    The Security Manager
    Miscellaneous Methods in System
Questions and Exercises: The Platform Environment

Regular Expressions

Test Harness
String Literals
Character Classes
Predefined Character Classes
Capturing Groups
Boundary Matchers
Methods of the Pattern Class
Methods of the Matcher Class
Methods of the PatternSyntaxException Class
Unicode Support
Additional Resources
Questions and Exercises: Regular Expressions

Trail: Deployment

Java Applets

Getting Started With Applets
    Defining an Applet Subclass
    Methods for Milestones
    Life Cycle of an Applet
    Applet’s Execution Environment
    Developing an Applet
    Deploying an Applet
        Deploying With the Applet Tag
Doing More With Applets
    Finding and Loading Data Files
    Defining and Using Applet Parameters
    Displaying Short Status Strings
    Displaying Documents in the Browser
    Invoking JavaScript Code From an Applet
    Invoking Applet Methods From JavaScript Code
    Handling Initialization Status With Event Handlers
    Manipulating DOM of Applet’s Web Page
    Displaying a Customized Loading Progress Indicator
    Writing Diagnostics to Standard Output and Error Streams
    Developing Draggable Applets
    Communicating With Other Applets
    Working With a Server-Side Application
        Network Client Applet Example
    What Applets Can and Cannot Do
Solving Common Applet Problems
Questions and Exercises: Applets

Java Web Start

Developing a Java Web Start Application
    Retrieving Resources
Deploying a Java Web Start Application
    Setting Up a Web Server
Displaying a Customized Loading Progress Indicator
Running a Java Web Start Application
Java Web Start and Security
Common Java Web Start Problems
Questions and Exercises: Java Web Start

Doing More With Java Rich Internet Applications

Setting Trusted Arguments and Secure Properties
    System Properties
    Accessing the Client Using JNLP API
    Accessing Cookies
Customizing the Loading Experience
Security in Rich Internet Applications
Questions and Exercises: Doing More With Rich Internet Applications

Deployment In-Depth

Deployment Toolkit
    Deploying an Applet
        Customizing the Loading Screen
        Embedding JNLP File in Applet Tag
    Deploying a Java Web Start Application
        Changing the Launch Button
        Deploying Without Codebase
    Checking the Client JRE Software Version
Java Network Launch Protocol
    Structure of the JNLP File
Deployment Best Practices
    Reducing the Download Time
    Avoiding Unnecessary Update Checks
    Signing JAR Files Only When Necessary
    Ensuring the Presence of the JRE Software
    Questions and Exercises: Deployment In-Depth

Packaging Programs in JAR Files

Using JAR Files: The Basics
    Creating a JAR File
    Viewing the Contents of a JAR File
    Extracting the Contents of a JAR File
    Updating a JAR File
    Running JAR-Packaged Software
Working with Manifest Files: The Basics
    Understanding the Default Manifest
    Modifying a Manifest File
    Setting an Application’s Entry Point
    Adding Classes to the JAR File’s Classpath
    Setting Package Version Information
    Sealing Packages within a JAR File
Signing and Verifying JAR Files
    Understanding Signing and Verification
    Signing JAR Files
    Verifying Signed JAR Files
Using JAR-related APIs
    The JarClassLoader Class
    The JarRunner Class
    Questions and Exercises: JAR

Trail: Creating a GUI With JFC/Swing

Getting Started with Swing

About the JFC and Swing
Compiling and Running Swing Programs

Learning Swing with the NetBeans IDE

Setting up the CelsiusConverter Project
NetBeans IDE Basics
Creating the CelsiusConverter GUI
Adjusting the CelsiusConverter GUI
Adding the Application Logic
Questions and Exercises: Learning Swing with the NetBeans IDE

Using Swing Components

Using Top-Level Containers
The JComponent Class
Using Text Components
    Text Component Features
    The Text Component API
How to Use Various Components
    How to Make Applets
    How to Use Buttons, Check Boxes, and Radio Buttons
    How to Use the ButtonGroup Component
    How to Use Color Choosers
    How to Use Combo Boxes
    How to Make Dialogs
    How to Use Editor Panes and Text Panes
    How to Use File Choosers
    How to Use Formatted Text Fields
    How to Make Frames (Main Windows)
    How to Use Internal Frames
    How to Use Labels
    How to Use Layered Panes
    How to Use Lists
    How to Use Menus
    How to Use Panels
    How to Use Password Fields
    How to Use Progress Bars
    How to Use Root Panes
    How to Use Scroll Panes
    How to Use Separators
    How to Use Sliders
    How to Use Spinners
    How to Use Split Panes
    How to Use Tabbed Panes
    How to Use Tables
    How to Use Text Areas
    How to Use Text Fields
    How to Use Tool Bars
    How to Use Tool Tips
    How to Use Trees
How to Use HTML in Swing Components
How to Use Models
How to Use Icons
How to Use Borders
Solving Common Component Problems
Questions and Exercises: Using Swing Components

Concurrency in Swing

Initial Threads
The Event Dispatch Thread
Worker Threads and SwingWorker
    Simple Background Tasks
    Tasks that Have Interim Results
    Canceling Background Tasks
    Bound Properties and Status Methods
    Questions and Exercises: Concurrency in Swing

Using Other Swing Features

How to Integrate with the Desktop Class
How to Create Translucent and Shaped Windows
How to Decorate Components with the JLayer Class
How to Use Actions
How to Use Swing Timers
How to Support Assistive Technologies
How to Use the Focus Subsystem
How to Use Key Bindings
How to Use Modality in Dialogs
How to Print Tables
How to Print Text
How to Create a Splash Screen
How to Use the System Tray
Solving Common Problems Using Other Swing Features

Laying Out Components Within a Container

A Visual Guide to Layout Managers
Using Layout Managers
How Layout Management Works
How to Use Various Layout Managers
How to Use BorderLayout
How to Use BoxLayout
How to Use CardLayout
How to Use FlowLayout
How to Use GridBagLayout
How to Use GridLayout
How to Use GroupLayout
    A GroupLayout Example
How to Use SpringLayout
Creating a Custom Layout Manager
Doing Without a Layout Manager (Absolute Positioning)
Solving Common Layout Problems
Questions and Exercises: Laying Out Components within a Container

Modifying the Look and Feel

How to Set the Look and Feel
The Synth Look and Feel
    A Synth Example
Nimbus Look and Feel
    Changing the Look of Nimbus
    Resizing a Component
    Changing the Color Theme
    For More Information

Drag and Drop and Data Transfer

Introduction to DnD
Default DnD Support
    Demo – BasicDnD
TransferHandler Class
    Export Methods
    Import Methods
TransferSupport Class
Setting the Drop Mode
    Demo – DropDemo
Choosing the Drop Action
    Demo – ChooseDropAction
Showing the Drop Location
Location Sensitive Drop
    Demo – LocationSensitiveDemo
Empty Table Drop
Drop Location Rendering
Top-Level Drop
Adding Cut, Copy and Paste (CCP)
CCP in a Text Component
CCP in a non-Text Component
Using and Creating a DataFlavor
Putting it All Together – DnD and CCP
Further Information
Solving Common Data Transfer Problems

Writing Event Listeners

Introduction to Event Listeners
General Information about Writing Event Listeners
Listeners Supported by Swing Components
Implementing Listeners for Commonly Handled Events
    How to Write an Action Listener
    How to Write a Caret Listener
    How to Write a Change Listener
    How to Write a Component Listener
    How to Write a Container Listener
    How to Write a Document Listener
    How to Write a Focus Listener
    How to Write an Internal Frame Listener
    How to Write an Item Listener
    How to Write a Key Listener
    How to Write a List Data Listener
    How to Write a List Selection Listener
    How to Write a Mouse Listener
    How to Write a Mouse-Motion Listener
    How to Write a Mouse-Wheel Listener
    How to Write a Property Change Listener
    How to Write a Table Model Listener
    How to Write a Tree Expansion Listener
    How to Write a Tree Model Listener
    How to Write a Tree Selection Listener
    How to Write a Tree-Will-Expand Listener
    How to Write an Undoable Edit Listener
    How to Write Window Listeners
Listener API Table
Solving Common Event-Handling Problems
Questions and Exercises: Writing Event Listeners

Performing Custom Painting

Creating the Demo Application (Step 1)
Creating the Demo Application (Step 2)
Creating the Demo Application (Step 3)
Refining the Design
A Closer Look at the Paint Mechanism
Solving Common Painting Problems
Questions and Exercises: Performing Custom Painting

Trail: Collections

Introduction to CollectionsInterfaces

The Collection Interface
The Set Interface
The List Interface
The Queue Interface
The Deque Interface
The Map Interface
Object Ordering
The SortedSet Interface
The SortedMap Interface
Summary of Interfaces
Questions and Exercises: Interfaces


Set Implementations
List Implementations
Map Implementations
Queue Implementations
Deque Implementations
Wrapper Implementations
Convenience Implementations
Summary of Implementations
Questions and Exercises: Implementations

AlgorithmsCustom Collection ImplementationsInteroperability

API Design

Trail: Internationalization


A Quick Example
    Before Internationalization
    After Internationalization
    Running the Sample Program
    Internationalizing the Sample Program

Setting the Locale

Creating a Locale
BCP 47 Extensions
Identifying Available Locales
The Scope of a Locale
Locale-Sensitive Services SPI

Isolating Locale-Specific Data

About the ResourceBundle Class
Preparing to Use a ResourceBundle
Backing a ResourceBundle with Properties Files
Using a ListResourceBundle
Customizing Resource Bundle Loading


Numbers and Currencies
    Using Predefined Formats
    Customizing Formats
Dates and Times
    Using Predefined Formats
    Customizing Formats
    Changing Date Format Symbols
    Dealing with Compound Messages
    Handling Plurals

Working with Text

Checking Character Properties
Comparing Strings
    Performing Locale-Independent Comparisons
    Customizing Collation Rules
    Improving Collation Performance
    Supplementary Characters as Surrogates
    Character and String APIs
    Sample Usage
    Design Considerations
    More Information
Detecting Text Boundaries
    About the BreakIterator Class
    Character Boundaries
    Word Boundaries
    Sentence Boundaries
    Line Boundaries
Converting Latin Digits to Other Unicode Digits
Converting Non-Unicode Text
    Byte Encodings and Strings
    Character and Byte Streams
Normalizing Text
Working with Bidirectional Text with the JTextComponent Class

Internationalization of Network Resources

Internationalized Domain Name

Trail: 2D Graphics

Overview of the Java 2D API Concepts

Java 2D Rendering
Geometric Primitives

Getting Started with GraphicsWorking with Geometry

Drawing Geometric Primitives
Drawing Arbitrary Shapes
Stroking and Filling Graphics Primitives

Working with Text APIs

Font Concepts
Text Layout Concepts
Physical and Logical Fonts
Measuring Text
Advanced Text Display
    Displaying Antialiased Text by Using Rendering Hints
    Using Text Attributes to Style Text
    Drawing Multiple Lines of Text
    Working with Bidirectional Text

Working with Images

Reading/Loading an Image
Drawing an Image
Creating and Drawing to an Image
Writing/Saving an Image


A Basic Printing Program
Using Print Setup Dialogs
Printing a Multiple Page Document
Working with Print Services and Attributes
Printing the Contents of a User Interface
Printing Support in Swing Components

Advanced Topics in Java2D

Transforming Shapes, Text, and Images
Clipping the Drawing Region
Compositing Graphics
Controlling Rendering Quality
Constructing Complex Shapes from Geometry Primitives
Supporting User Interaction

Trail: Sound

Overview of the Sampled Package
Accessing Audio System Resources
Playing Back Audio
Capturing Audio
Processing Audio with Controls
Using Files and Format Converters
Overview of the MIDI Package
Accessing MIDI System Resources
Transmitting and Receiving MIDI Messages
Introduction to Sequencers
Using Sequencer Methods
Using Advanced Sequencer Features
Synthesizing Sound
Introduction to the Service Provider Interfaces
Providing Sampled-Audio Services
Providing MIDI Services

Trail: JavaBeans(TM)

Quick Start

Creating a Project
A Button is a Bean
Wiring the Application
Using a Third-Party Bean

Writing JavaBeans Components

Using a BeanInfo

Advanced JavaBeans Topics

Bean Persistence
Long Term Persistence
Bean Customization

Trail: JDBC(TM) Database Access

JDBC Introduction

JDBC Architecture
A Relational Database Overview

JDBC Basics

Getting Started
Processing SQL Statements with JDBC
Establishing a Connection
Connecting with DataSource Objects
Handling SQLExceptions
Setting Up Tables
Retrieving and Modifying Values from Result Sets
Using Prepared Statements
Using Transactions
Using RowSet Objects
Using JdbcRowSet Objects
Using CachedRowSetObjects
Using JoinRowSet Objects
Using FilteredRowSet Objects
Using WebRowSet Objects
Using Advanced Data Types
Using Large Objects
Using SQLXML Objects
Using Array Objects
Using DISTINCT Data Type
Using Structured Objects
Using Customized Type Mappings
Using Datalink Objects
Using RowId Objects
Using Stored Procedures
Using JDBC with GUI API

Trail: Java Management Extensions (JMX)

Overview of the JMX Technology

Why Use the JMX Technology?
Architecture of the JMX Technology
Monitoring and Management of the Java Virtual Machine

Introducing MBeans

Standard MBeans

NotificationsRemote Management

Exposing a Resource for Remote Management By JConsole
Creating a Custom JMX Client

Trail: Java API for XML Processing (JAXP)

Introduction to JAXP

Overview of the Packages
Simple API for XML APIs
Document Object Model APIs
Extensible Stylesheet Language Transformations APIs
Streaming API for XML APIs
Finding the JAXP Sample Programs
Where Do You Go From Here?

Simple API for XML

When to Use SAX
Parsing an XML File Using SAX
Implementing SAX Validation
Handling Lexical Events
Using the DTDHandler and EntityResolver
Further Information

Document Object Model

When to Use DOM
Reading XML Data into a DOM
Validating with XML Schema
Further Information

Extensible Stylesheet Language Transformations

Introducing XSL, XSLT, and XPath
How XPath Works
Writing Out a DOM as an XML File
Generating XML from an Arbitrary Data Structure
Transforming XML Data with XSLT

Streaming API for XML

Why StAX?
Using StAX
Oracle’s Streaming XML Parser Implementation
Example Code
Further Information

Trail: RMI

An Overview of RMI Applications
Writing an RMI Server
    Designing a Remote Interface
    Implementing a Remote Interface
Creating a Client Program
Compiling and Running the Example
    Compiling the Example Programs
    Running the Example Programs

Trail: Security Features in Java SE

Security Features OverviewQuick Tour of Controlling Applets

Observe Applet Restrictions
Set up a Policy File to Grant the Required Permission
    Start Policy Tool
    Grant the Required Permission
    Save the Policy File
See the Policy File Effects

Quick Tour of Controlling Applications

Observe Application Freedom
See How to Restrict Applications
Set up the Policy File to Grant the Required Permissions
    Open the Policy File
    Grant the Required Permissions
    Save the Policy File
See the Policy File Effects

API and Tools Use for Secure Code and File ExchangesSigning Code and Granting It Permissions

Steps for the Code Signer
    Download and Try the Sample Application
    Create a JAR File Containing the Class File
    Generate Keys
    Sign the JAR File
    Export the Public Key Certificate
Steps for the Code Receiver
    Observe the Restricted Application
    Import the Certificate as a Trusted Certificate
    Set Up a Policy File to Grant the Required Permission
        Start Policy Tool
        Specify the Keystore
        Add a Policy Entry with a SignedBy Alias
        Save the Policy File
    See the Policy File Effects

Exchanging Files

Steps for the Contract Sender
    Create a JAR File Containing the Contract
    Generate Keys
    Sign the JAR File
    Export the Public Key Certificate
Steps for the Contract Receiver
    Import the Certificate as a Trusted Certificate
    Verify the JAR File Signature

Generating and Verifying Signatures

Generating a Digital Signature
    Prepare Initial Program Structure
    Generate Public and Private Keys
    Sign the Data
    Save the Signature and the Public Key in Files
    Compile and Run the Program
Verifying a Digital Signature
    Prepare Initial Program Structure
    Input and Convert the Encoded Public Key Bytes
    Input the Signature Bytes
    Verify the Signature
    Compile and Run the Program
Weaknesses and Alternatives

Implementing Your Own Permission

The HighScore Class
The HighScorePermission Class
A Sample Policy File
Putting It All Together
    Steps for the HighScore Developer (Chris)
    Steps for the ExampleGame Developer (Terry)
    Steps for a User Running ExampleGame (Kim)

Trail: The Extension Mechanism

Creating and Using Extensions

Installed Extensions
Download Extensions
Understanding Extension Class Loading

Making Extensions Secure

Setting Privileges for Extensions
Sealing Packages in Extensions

Trail: The Reflection API


Retrieving Class Objects
Examining Class Modifiers and Types
Discovering Class Members


    Obtaining Field Types
    Retrieving and Parsing Field Modifiers
    Getting and Setting Field Values
    Obtaining Method Type Information
    Retrieving and Parsing Method Modifiers
    Invoking Methods
    Finding Constructors
    Retrieving and Parsing Constructor Modifiers
    Creating New Class Instances

Arrays and Enumerated Types

    Identifying Array Types
    Creating New Arrays
    Getting and Setting Arrays and Their Components
Enumerated Types
    Examining Enums
    Getting and Setting Fields with Enum Types

Trail: Custom Networking

Overview of Networking

What You May Already Know About Networking in Java
Networking Basics

Working with URLs

What Is a URL?
Creating a URL
Parsing a URL
Reading Directly from a URL
Connecting to a URL
Reading from and Writing to a URLConnection

All About Sockets

What Is a Socket?
Reading from and Writing to a Socket
Writing the Server Side of a Socket

All About Datagrams

What Is a Datagram?
Writing a Datagram Client and Server
Broadcasting to Multiple Recipients

Programmatic Access to Network Parameters

What Is a Network Interface?
Retrieving Network Interfaces
Listing Network Interface Addresses
Network Interface Parameters

Working With Cookies

HTTP State Management With Cookies
CookieHandler Callback Mechanism
Default CookieManager
Custom CookieManager

Trail: Bonus


Defining Simple Generics
Generics and Subtyping
Generic Methods
Interoperating with Legacy Code
The Fine Print
Class Literals as Runtime-Type Tokens
More Fun with Wildcards
Converting Legacy Code to Use Generics

Full-Screen Exclusive Mode API

Full-Screen Exclusive Mode
Display Mode
Passive vs. Active Rendering
Double Buffering and Page Flipping
BufferStrategy and BufferCapabilities

Preparation for Java Programmer Language Certification

Programmer Level I Exam
Programmer Level II Exam
Java SE 7 Upgrade Exam

Trail: Java Naming and Directory Interface

Naming and Directory Concepts

Directory Concepts

Overview of JNDI

Naming Package
Directory and LDAP Packages
Event and Service Provider Packages

Software Setup

LDAP Setup
Java Application Setup

Naming and Directory Operations

Naming Exceptions
Lookup an Object
List the Context
Add, Replace or Remove a Binding
Create and Destroy Subcontexts
Attribute Names
Read Attributes
Modify Attributes
Add, Replace Bindings with Attributes
    Basic Search
    Result Count
    Time Limit
Trouble Shooting Tips

Advanced Topics for LDAP Users

    How LDAP Operations Map to JNDI APIs
    How LDAP Error Codes Map to JNDI Exceptions
    Modes of Authenticating to LDAP
    Authentication Mechanisms
    SSL and Custom Sockets
More LDAP Operations
    LDAP Compare
    Search Results
     LDAP Unsolicited Notifications
Connection Management
Frequently Asked Questions

Java Objects in the Directory

Storing and Reading Objects
Serializable Objects

New features in JDK 5.0 and JDK 6

Retrieving Distinguished Name
Standard LDAP Controls
Paged Results Control
Sort Control
Manage Referral Control
Manipulating LdapName (Distinguished Name)
Manipulating Relative Distringuished Name (RDN)
Setting Timeout for Ldap Operations

Trail: Sockets Direct Protocol

Understanding the Sockets Direct Protocol

Creating an SDP Configuration File
Enabling the SDP Protocol
Debugging SDP
Technical Issues with SDP
Solaris and Linux Support
Supported Java APIs
For More Information

Trail: Java Architecture for XML Binding

Introduction to JAXB

JAXB Architecture
Representing XML Content
Binding XML Schemas
Customizing Generated Classes and Java Program Elements
JAXB Examples
Basic Examples
Customizing JAXB Bindings
Java-to-Schema Examples
For More Information
Source :

Understanding Java Garbage Collection

What are the benefits of knowing how garbage collection (GC) works in Java? Satisfying the intellectual curiosity as a software engineer would be a valid cause, but also, understanding how GC works can help you write much better Java applications.

This is a very personal and subjective opinion of mine, but I believe that a person well versed in GC tends to be a better Java developer. If you are interested in the GC process, that means you have experience in developing applications of certain size. If you have thought carefully about choosing the right GC algorithm, that means you completely understand the features of the application you have developed. Of course, this may not be common standards for a good developer. However, few would object when I say that understanding GC is a requirement for being a great Java developer.

This is the first of a series of “Become a Java GC Expert” articles. I will cover the GC introduction this time, and in the next article, I will talk about analyzing GC status and GC tuning examples from NHN.

The purpose of this article is to introduce GC to you in an easy way. I hope this article proves to be very helpful. Actually, my colleagues have already published a few great articles on Java Internals which became quite popular on Twitter. You may refer to them as well.

Returning back to Garbage Collection, there is a term that you should know before learning about GC. The term is “stop-the-world.” Stop-the-world will occur no matter which GC algorithm you choose. Stop-the-worldmeans that the JVM is stopping the application from running to execute a GC. When stop-the-world occurs, every thread except for the threads needed for the GC will stop their tasks. The interrupted tasks will resume only after the GC task has completed. GC tuning often means reducing this stop-the-world time.

Generational Garbage Collection

Java does not explicitly specify a memory and remove it in the program code. Some people sets the relevant object to null or use System.gc() method to remove the memory explicitly. Setting it to null is not a big deal, but calling System.gc() method will affect the system performance drastically, and must not be carried out. (Thankfully, I have not yet seen any developer in NHN calling this method.)

In Java, as the developer does not explicitly remove the memory in the program code, the garbage collector finds the unnecessary (garbage) objects and removes them. This garbage collector was created based on the following two hypotheses. (It is more correct to call them suppositions or preconditions, rather than hypotheses.)


  • Most objects soon become unreachable.
  • References from old objects to young objects only exist in small numbers.


These hypotheses are called the weak generational hypothesis. So in order to preserve the strengths of this hypothesis, it is physically divided into two – young generation and old generation – in HotSpot VM.

Young generation: Most of the newly created objects are located here. Since most objects soon become unreachable, many objects are created in the young generation, then disappear. When objects disappear from this area, we say a “minor GC” has occurred.

Old generation: The objects that did not become unreachable and survived from the young generation are copied here. It is generally larger than the young generation. As it is bigger in size, the GC occurs less frequently than in the young generation. When objects disappear from the old generation, we say a “major GC” (or a “full GC“) has occurred.

Let’s look at this in a chart.

Figure 1: GC Area & Data Flow.

Figure 1: GC Area & Data Flow.

The permanent generation from the chart above is also called the “method area,” and it stores classes or interned character strings. So, this area is definitely not for objects that survived from the old generation to stay permanently. A GC may occur in this area. The GC that took place here is still counted as a major GC.

Some people may wonder:

What if an object in the old generation need to reference an object in the young generation?

To handle these cases, there is something called the a “card table” in the old generation, which is a 512 byte chunk. Whenever an object in the old generation references an object in the young generation, it is recorded in this table. When a GC is executed for the young generation, only this card table is searched to determine whether or not it is subject for GC, instead of checking the reference of all the objects in the old generation. This card table is managed with write barrier. This write barrier is a device that allows a faster performance for minor GC. Though a bit of overhead occurs because of this, the overall GC time is reduced.

Figure 2: Card Table Structure.

Figure 2: Card Table Structure.

Composition of the Young Generation

In order to understand GC, let’s learn about the young generation, where the objects are created for the first time. The young generation is divided into 3 spaces.


  • One Eden space
  • Two Survivor spaces


There are 3 spaces in total, two of which are Survivor spaces. The order of execution process of each space is as below:


  1. The majority of newly created objects are located in the Eden space.
  2. After one GC in the Eden space, the surviving objects are moved to one of the Survivor spaces.
  3. After a GC in the Eden space, the objects are piled up into the Survivor space, where other surviving objects already exist.
  4. Once a Survivor space is full, surviving objects are moved to the other Survivor space. Then, the Survivor space that is full will be changed to a state where there is no data at all.
  5. The objects that survived these steps that have been repeated a number of times are moved to the old generation.


As you can see by checking these steps, one of the Survivor spaces must remain empty. If data exists in both Survivor spaces, or the usage is 0 for both spaces, then take that as a sign that something is wrong with your system.

The process of data piling up into the old generation through minor GCs can be shown as in the below chart:

Figure 3: Before & After a GC.

Figure 3: Before & After a GC.

Note that in HotSpot VM, two techniques are used for faster memory allocations. One is called “bump-the-pointer,” and the other is called “TLABs (Thread-Local Allocation Buffers).”

Bump-the-pointer technique tracks the last object allocated to the Eden space. That object will be located on top of the Eden space. And if there is an object created afterwards, it checks only if the size of the object is suitable for the Eden space. If the said object seems right, it will be placed in the Eden space, and the new object goes on top. So, when new objects are created, only the lastly added object needs to be checked, which allows much faster memory allocations. However, it is a different story if we consider a multithreaded environment. To save objects used by multiple threads in the Eden space for Thread-Safe, an inevitable lock will occur and the performance will drop due to the lock-contention. TLABs is the solution to this problem in HotSpot VM. This allows each thread to have a small portion of its Eden space that corresponds to its own share. As each thread can only access to their own TLAB, even the bump-the-pointer technique will allow memory allocations without a lock.

This has been a quick overview of the GC in the young generation. You do not necessarily have to remember the two techniques that I have just mentioned. You will not go to jail for not knowing them. But please remember that after the objects are first created in the Eden space, and the long-surviving objects are moved to the old generation through the Survivor space.

GC for the Old Generation

The old generation basically performs a GC when the data is full. The execution procedure varies by the GC type, so it would be easier to understand if you know different types of GC.

According to JDK 7, there are 5 GC types.


  1. Serial GC
  2. Parallel GC
  3. Parallel Old GC (Parallel Compacting GC)
  4. Concurrent Mark & Sweep GC  (or “CMS”)
  5. Garbage First (G1) GC


Among these, the serial GC must not be used on an operating server. This GC type was created when there was only one CPU core on desktop computers. Using this serial GC will drop the application performance significantly.

Now let’s learn about each GC type.

Serial GC (-XX:+UseSerialGC)

The GC in the young generation uses the type we explained in the previous paragraph. The GC in the old generation uses an algorithm called “mark-sweep-compact.”


  1. The first step of this algorithm is to mark the surviving objects in the old generation.
  2. Then, it checks the heap from the front and leaves only the surviving ones behind (sweep).
  3. In the last step, it fills up the heap from the front with the objects so that the objects are piled up consecutively, and divides the heap into two parts: one with objects and one without objects (compact).


The serial GC is suitable for a small memory and a small number of CPU cores.

Parallel GC (-XX:+UseParallelGC)

Figure 4: Difference between the Serial GC and Parallel GC.

Figure 4: Difference between the Serial GC and Parallel GC.

From the picture, you can easily see the difference between the serial GC and parallel GC. While the serial GC uses only one thread to process a GC, the parallel GC uses several threads to process a GC, and therefore, faster. This GC is useful when there is enough memory and a large number of cores. It is also called the “throughput GC.”

Parallel Old GC(-XX:+UseParallelOldGC)

Parallel Old GC was supported since JDK 5 update. Compared to the parallel GC, the only difference is the GC algorithm for the old generation. It goes through three steps: mark – summary – compaction. The summary step identifies the surviving objects separately for the areas that the GC have previously performed, and thus different from the sweep step of the mark-sweep-compact algorithm. It goes through a little more complicated steps.

CMS GC (-XX:+UseConcMarkSweepGC)

Figure 5: Serial GC & CMS GC.

Figure 5: Serial GC & CMS GC.

As you can see from the picture, the Concurrent Mark-Sweep GC is much more complicated than any other GC types that I have explained so far. The early initial mark step is simple. The surviving objects among the objects the closest to the classloader are searched. So, the pausing time is very short. In the concurrent mark step, the objects referenced by the surviving objects that have just been confirmed are tracked and checked. The difference of this step is that it proceeds while other threads are processed at the same time. In the remarkstep, the objects that were newly added or stopped being referenced in the concurrent mark step are checked. Lastly, in the concurrent sweep step, the garbage collection procedure takes place. The garbage collection is carried out while other threads are still being processed. Since this GC type is performed in this manner, the pausing time for GC is very short. The CMS GC is also called the low latency GC, and is used when the response time from all applications is crucial.

While this GC type has the advantage of short stop-the-world time, it also has the following disadvantages.


  • It uses more memory and CPU than other GC types.
  • The compaction step is not provided by default.


You need to carefully review before using this type. Also, if the compaction task needs to be carried out because of the many memory fragments, the stop-the-world time can be longer than any other GC types. You need to check how often and how long the compaction task is carried out.


Finally, let’s learn about the garbage first (G1) GC.

Figure 6:&nbsp;Layout of G1 GC.

Figure 6: Layout of G1 GC.

If you want to understand G1 GC, forget everything you know about the young generation and the old generation. As you can see in the picture, one object is allocated to each grid, and then a GC is executed. Then, once one area is full, the objects are allocated to another area, and then a GC is executed. The steps where the data moves from the three spaces of the young generation to the old generation cannot be found in this GC type. This type was created to replace the CMS GC, which has causes a lot of issues and complaints in the long term.

The biggest advantage of the G1 GC is its performance. It is faster than any other GC types that we have discussed so far. But in JDK 6, this is called an early access and can be used only for a test. It is officially included in JDK 7. In my personal opinion, we need to go through a long test period (at least 1 year) before NHN can use JDK7 in actual services, so you probably should wait a while. Also, I heard a few times that a JVM crash occurred after applying the G1 in JDK 6. Please wait until it is more stable.

I will talk about the GC tuning in the next issue, but I would like to ask you one thing in advance. If the size and the type of all objects created in the application are identical, all the GC options for WAS used in our company can be the same. But the size and the lifespan of the objects created by WAS vary depending on the service, and the type of equipment varies as well. In other words, just because a certain service uses the GC option “A,” it does not mean that the same option will bring the best results for a different service. It is necessary to find the best values for the WAS threads, WAS instances for each equipment and each GC option by constant tuning and monitoring. This did not come from my personal experience, but from the discussion of the engineers making Oracle JVM for JavaOne 2010.

In this issue, we have only glanced at the GC for Java. Please look forward to our next issue, where I will talk about how to monitor the Java GC status and tune GC.

I would like to note that I referred to a new book released in December 2011 called “Java Performance” (Amazon, it can also be viewed from safari online, if the company provides an account), as well as “Memory Management in the Java HotSpotTM Virtual Machine,” a white paper provided by the Oracle website. (The book is different from “Java Performance Tuning.”)

By Sangmin Lee, Senior Engineer at Performance Engineering Lab, NHN Corporation.

Source :

Struts 2 : Video Tutorial

Struts 2 Tutorial 01 – Introduction To MVC

Struts 2 Tutorial 02 – Introduction to Struts 2

Struts 2 Tutorial 03 – Setting Up

Struts 2 Tutorial 04 Part 1 – Writing a Struts 2 Application

Struts 2 Tutorial 04 Part 2 – Writing a Struts 2 Application

Struts 2 Tutorial 05 – Understanding Namespaces

Struts 2 Tutorial 06 – A Tag And A Business Service

Struts 2 Tutorial 07 – The ValueStack

Struts 2 Tutorial 08 – Accessing Input Parameters

Struts 2 Tutorial 09 – Post requests to actions

Struts 2 Tutorial 10 – Login Action and Best Practices

Struts 2 Tutorial 11 – Login Action and Best Practices Part 2

Struts 2 Tutorial 12 – Action Wildcards

Struts 2 Tutorial 13 – The ActionSupport Class

Struts 2 Tutorial 14 – Configuring methods in Action mappings

Struts 2 Tutorial 15 – Using Model Objects

Struts 2 Tutorial 16 – Introducing Interceptors


ScheduledExecutorService java.util.concurrent Tutorial

The java.util.concurrent.ScheduledExecutorService is anExecutorService which can schedule tasks to run after a delay, or to execute repeatedly. Tasks are executed asynchronously by a worker thread, and not by the thread handing the task to the ScheduledExecutorService.

ScheduledExecutorService Implementations

Since ScheduledExecutorService is an interface, you will have to use its implementation in the java.util.concurrent package, in order to use it.ScheduledExecutorService as the following implementation:

  • ScheduledThreadPoolExecutor

Creating a ScheduledExecutorService

How you create an ScheduledExecutorService depends on the implementation you use. However, you can use the Executors factory class to create ScheduledExecutorService instances too. Here is an example:

ScheduledExecutorService scheduledExecutorService =


ScheduledExecutorService Usage

Once you have created a ScheduledExecutorService you use it by calling one of its methods:

  • schedule (Callable task, long delay, TimeUnit timeunit)
  • schedule (Runnable task, long delay, TimeUnit timeunit)
  • scheduleAtFixedRate (Runnable, long initialDelay, long period, TimeUnit timeunit)
  • scheduleWithFixedDelay (Runnable, long initialDelay, long period, TimeUnit timeunit)

I will briefly cover each of these methods below.

schedule (Callable task, long delay, TimeUnit timeunit)

This method schedules the given Callable for execution after the given delay.

The method returns a ScheduledFuture which you can use to either cancel the task before it has started executing, or obtain the result once it is executed.

Here is an example:

ScheduledExecutorService scheduledExecutorService =

ScheduledFuture scheduledFuture =
    scheduledExecutorService.schedule(new Callable() {
        public Object call() throws Exception {
            return "Called!";

System.out.println("result = " + scheduledFuture.get());


This example outputs:

result = Called!

schedule (Runnable task, long delay, TimeUnit timeunit)

This method works like the method version taking a Callable as parameter, except a Runnable cannot return a value, so the ScheduledFuture.get()method returns null when the task is finished.

scheduleAtFixedRate (Runnable, long initialDelay, long period, TimeUnit timeunit)

This method schedules a task to be executed periodically. The task is executed the first time after the initialDelay, and then recurringly every time theperiod expires.

If any execution of the given task throws an exception, the task is no longer executed. If no exceptions are thrown, the task will continue to be executed until the ScheduledExecutorService is shut down.

If a task takes longer to execute than the period between its scheduled executions, the next execution will start after the current execution finishes. The scheduled task will not be executed by more than one thread at a time.

scheduleWithFixedDelay (Runnable, long initialDelay, long period, TimeUnit timeunit)

This method works very much like scheduleAtFixedRate() except that theperiod is interpreted differently.

In the scheduleAtFixedRate() method the period is interpreted as a delay between the start of the previous execution, until the start of the next execution.

In this method, however, the period is interpreted as the delay between the endof the previous execution, until the start of the next. The delay is thus between finished executions, not between the beginning of executions.


Source :

ExecutorService of java.util.concurrent Tutorial

The java.util.concurrent.ExecutorService interface represents an asynchronous execution mechanism which is capable of executing tasks in the background.

An ExecutorService is thus very similar to a thread pool. In fact, the implementation of ExecutorService present in the java.util.concurrentpackage is a thread pool implementation.

Here is a diagram illustrating a thread delegating a task to an ExecutorServicefor asynchronous execution:

A thread delegating a task to an ExecutorService for asynchronous execution.
A thread delegating a task to an ExecutorService for asynchronous execution.


ExecutorService Implementations

Since ExecutorService is an interface, you need to its implementations in order to make any use of it. The ExecutorService has the following implementation in the java.util.concurrent package:


Creating an ExecutorService

How you create an ExecutorService depends on the implementation you use. However, you can use the Executors factory class to createExecutorService instances too. Here are a few examples:

ExecutorService executorService1 = Executors.newSingleThreadExecutor();

ExecutorService executorService2 = Executors.newFixedThreadPool(10);

ExecutorService executorService3 = Executors.newScheduledThreadPool(10);


ExecutorService Usage

There are a few different ways to delegate tasks for execution to anExecutorService:

  • execute(Runnable)
  • submit(Runnable)
  • submit(Callable)
  • invokeAny(…)
  • invokeAll(…)

I will take a look at each of these methods in the following sections.



The execute(Runnable) method takes a java.lang.Runnable object, and executes it asynchronously. Here is an example.

ExecutorService executorService = Executors.newSingleThreadExecutor();

executorService.execute(new Runnable() {
    public void run() {
        System.out.println("Asynchronous task");


There is no way of obtaining the result of the executed Runnable, if necessary. You will have to use a Callable for that (explained in the following sections).



The submit(Runnable) method also takes a Runnable implementation, but returns a Future object. This Future object can be used to check if theRunnable as finished executing.

Here is a submit() example:

Future future = executorService.submit(new Runnable() {
    public void run() {
        System.out.println("Asynchronous task");

future.get();  //returns null if the task has finished correctly.



The submit(Callable) method is similar to the submit(Runnable) method except for the type of parameter it takes. The Callable instance is very similar to a Runnable except that its call() method can return a result. method cannot return a result.

The Callable‘s result can be obtained via the Future object returned by thesubmit(Callable) method. Here is a code example:

Future future = executorService.submit(new Callable(){
    public Object call() throws Exception {
        System.out.println("Asynchronous Callable");
        return "Callable Result";

System.out.println("future.get() = " + future.get());

The above code example will output this:

Asynchronous Callable
future.get() = Callable Result



The invokeAny() method takes a collection of Callable objects, or subinterfaces of Callable. Invoking this method does not return a Future, but returns the result of one of the Callable objects. You have no guarantee about which of the Callable‘s results you get. Just one of the ones that finish.

If one of the tasks complete (or throws an exception), the rest of the Callable‘s are cancelled.

Here is a code example:

ExecutorService executorService = Executors.newSingleThreadExecutor();

Set<Callable<String>> callables = new HashSet<Callable<String>>();

callables.add(new Callable<String>() {
    public String call() throws Exception {
        return "Task 1";
callables.add(new Callable<String>() {
    public String call() throws Exception {
        return "Task 2";
callables.add(new Callable<String>() {
    public String call() throws Exception {
        return "Task 3";

String result = executorService.invokeAny(callables);

System.out.println("result = " + result);


This code example will print out the object returned by one of the Callable‘s in the given collection. I have tried running it a few times, and the result changes. Sometimes it is “Task 1”, sometimes “Task 2” etc.



The invokeAll() method invokes all of the Callable objects you pass to it in the collection passed as parameter. The invokeAll() returns a list of Futureobjects via which you can obtain the results of the executions of each Callable.

Keep in mind that a task might finish due to an exception, so it may not have “succeeded”. There is no way on a Future to tell the difference.

Here is a code example:

ExecutorService executorService = Executors.newSingleThreadExecutor();

Set<Callable<String>> callables = new HashSet<Callable<String>>();

callables.add(new Callable<String>() {
    public String call() throws Exception {
        return "Task 1";
callables.add(new Callable<String>() {
    public String call() throws Exception {
        return "Task 2";
callables.add(new Callable<String>() {
    public String call() throws Exception {
        return "Task 3";

List<Future<String>> futures = executorService.invokeAll(callables);

for(Future<String> future : futures){
    System.out.println("future.get = " + future.get());



Closing an ExecutorService

When you are done using the ExecutorService you should shut it down, so the threads do not keep running.

For instance, if your application is started via a main() method and your main thread exits your application, the application will keep running if you have an activeExexutorService in your application. The active threads inside thisExecutorService prevents the JVM from shutting down.

To terminate the threads inside the ExecutorService you call its shutdown()method. The ExecutorService will not shut down immediately, but it will no longer accept new tasks, and once all threads have finished current tasks, theExecutorService shuts down. All tasks submitted to the ExecutorServicebefore shutdown() is called, are executed.

If you want to shut down the ExecutorService immediately, you can call theshutdownNow() method. This will attempt to stop all executing tasks right away, and skips all submitted but non-processed tasks. There are no guarantees given about the executing tasks. Perhaps they stop, perhaps the execute until the end. It is a best effort attempt.

Source :