algorithm to merge two sorted arrays without additional array

Algorithm to merge two sorted arrays: Here we use merge sort logic but with a small change; we take the larger size array and start inserting elements from end of that array.

package algorithms.sort;

/**
 * Algorithm to merge two sorted arrays without additional array,
 * provided one of the two arrays has the size of the combination
 * sizes of two arrays
 *
 * @author ntallapa
 *
 */
public class Merge2SortedArraysWO3rdArray {

	public void mergeArrays(int[] aArr, int aSize, int[] bArr, int bSize) {
		// pointer to end of the first sorted array
		int aIdx=aArr.length-1;
		// pointer to end of the second sorted array (pointer at 100 in below array bArr)
		int bIdx=bArr.length-aArr.length-1;
		// pointer to end of the second sorted array (pointer at last 0)
		int cIdx=bArr.length-1;

		/**
		 * whichever is higher in two arrays, place that
		 * element in last position of the bigger array
		 */
		while(cIdx>=0 && aIdx>=0 && bIdx>=0) {
			if(aArr[aIdx] > bArr[bIdx]) {
				bArr[cIdx--] = aArr[aIdx--];
			} else {
				bArr[cIdx--] = bArr[bIdx--];
			}
		}

		// run through the left over elements of array aArr
		while(aIdx>=0) {
			bArr[cIdx--] = aArr[aIdx--];
		}

		// run through the left over elements of array bArr
		while(bIdx>0) {
			bArr[cIdx--] = bArr[bIdx--];
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Merge2SortedArraysWO3rdArray mergeArrays = new Merge2SortedArraysWO3rdArray();
		int[] aArr = {3,7,12,16};
		int[] bArr = {1,4,9,100,0,0,0,0};

		mergeArrays.mergeArrays(aArr, aArr.length, bArr, bArr.length);

		for(int i: bArr) {
			System.out.println(i);
		}
	}
}

Output:

1 3 4 7 9 12 16 100
Advertisements

find all pairs in an array, that sum up to particular number with best complexity

Here we discuss two possible algorithms

  • algorithm with the time complexity O(n) and with no additional space complexity
  • algorithm which uses additional hashmap data structure which reduces the time complexity to O(2n) at the cost of additional space complexity O(n)
  • brute force algorithm with time complexity of O(n^2)

Algorithm with the time complexity O(n) and with no additional space complexity

        /**
	 * Find the pair in an array whose sum with complexity O(n). This assumes
	 * the array passed is sorted array and there are no duplicates in the array
	 * 
	 * @param arr
	 *            input array of elements
	 * @param k
	 *            sum for which pair of array elements needs to be searched
	 */
	public void getPair2(int[] arr, int k) {
		int start = 0;
		int end = arr.length - 1;
		int sum = 0;

		// output array to record matching pairs
		StringBuilder arrs = new StringBuilder();

		while (start < end) {
			sum = arr[start] + arr[end];
			if (sum == k) {
				// we have found one pair, add it to our output array
				arrs.append(arr[start] + "," + arr[end] + ";");
				start++;
				end--;
			} else if (sum < k) {
				// if the sum of the pair is less than the sum we are searching
				// then increment the start pointer which would give us the sum
				// more than our current sum as the array is sorted
				start++;
			} else {
				// if the sum of the pair is greater than the sum we are searching
				// then decrement the end pointer which would give us the sum
				// less than our current sum as the array is sorted
				end--;
			}
		}
		System.out.println(arrs.toString());
	}

Output: 1,5;2,4;

Algorithm which uses additional hashmap data structure which reduces the time complexity to O(2n) at the cost of additional space complexity O(n)

/**
	 * Find the pair in an array whose sum with complexity O(2n)
	 * 
	 * @param arr
	 *            input array of elements
	 * @param k
	 *            sum for which pair of array elements needs to be searched
	 * @return string of combination of array pairs
	 */
	public String getPair(int[] arr, int k) {
		HashMap<Integer, Integer> hm = new HashMap<Integer, Integer>();
		String result = "";

		/**
		 * First store array elements into hashmap with key as the value of the
		 * array This has time complexity of O(n) and space complexity of O(n)
		 */
		for (int i = 0; i < arr.length; i++) {
			hm.put(arr[i], arr[i]);
		}

		/**
		 * Try getting the hashmap value at key (sum-array_element) If it
		 * exists, it means array_element and sum-array_element is the pair
		 * thats forms sum 'k' This has time complexity of O(n)
		 */
		for (int i = 0; i < arr.length; i++) {
			if (hm.get(k - arr[i]) != null) {
				result += arr[i] + "," + (k - arr[i]) + ";";
			}
		}
		return result;
	}

Output: Pair of elements at O(2n) time complexity and O(n) space complexity: 4,2;2,4;5,1;1,5;

Brute force algorithm with time complexity of O(n^2)

/**
	 * Find the pair in an array whose sum with complexity O(n^2)
	 * 
	 * @param arr
	 *            input array of elements
	 * @param k
	 *            sum for which pair of array elements needs to be searched
	 * @return string of combination of array pairs
	 */
	public String findPair(int[] arr, int k) {
		int i = 0, j = arr.length - 1;
		String result = "";
		while (i < j) {
			while (i < j) {
				if (arr[i] + arr[j] == k) {
					result += arr[i] + "," + arr[j] + ";";
				}
				j--;
			}
			i++;
			j = arr.length - 1;
		}
		return result;
	}

Output: Pair of elements at O(n^2) time complexity and no additional space complexity: 4,2;5,1;

Immutable Objects and Strings in Java

Why are Strings made immutable?
Security Reasons: as strings are used in class loaders, if it is made mutable it could lead to a potential security threat.
Efficient Memory Usage: We use string for whole lot of reasons with the concept of ‘literal pool/string pool’, when string literal is recreated it points to the already existing literal instead of creating new string in the pool memory.
Note: Along with Strings all the wrappers of primitive data types are made immutable.

Whys is String made final?
In order not to override the existing String class to remove immutable property where we would lose the above mentioned advantages it is made final.

Disadvantages of Strings being immutable?
And the negative side of immutable strings is that even a small change to a big string could lead to the construction of entire string again which is both time and space inefficient. In these scenarios we should go for StringBuffer/StringBuilder.

String pool memory and garbage collection:
These two concepts are contradictory in the sense, intention of coming up with pool concept is for the memory efficiency and for this reason GC wont act on it.
Since string pool memory does not come under the scanner of JAVA’s Garbage Collector (GC); once a string literal is put into pool memory it never dies. The inference from this is NEVER EVER store any user sensitive or confidential information in strings because a hacker can always dump the heap which would give away all the secure information.

String used as hashmap keys because of their immutable property:
Hashmap’s key constraint is that once after inserting key-value pair into it, one should not change the key value (with which hashcode is tied up with) as we manipulate the correct bucket based on the hascode which in turn is associated to the key value. And hence after inserting the key-value pair if one changes the key value, its hashcode changes and hence lookup of this pair ends up in returning null. Because of String’s immutable property one can safely make use of String as key in hashmaps.

other most frequently asked java questions

difference between concurrenthashmap and hashtable


In short, hashtable is synchronized at whole map level where as concurrenthashmap is synchronized at bucket level. Here are the differences:

  • read is completely not synchronized in concurrenthashmap
  • Iteratable/Enumerator does not throw concurrent modification exception while iterting in case the map is modified while iterating
  • write is synchronized only at the bucket level instead at the table level

importance of volatility, atomicity and synchronization


volatile: When a variable is declared volatile, any update to that variable is made directly to main memory instead of CPU cache and hence it guarantees the visibility of changes across threads

private volatile boolean flag;

public void run() {
while(!flag) {
//do some work
}
}

public void markFlag() {
flag = true;
}

atomicity: When a variable is declared atomic, it ensures the operations made on the variable are atomic in nature, it uses compare-and-swap low level cpu operation to accomplish this without the need of synchronization.

synchronization: traditional way of acquiring locks to do read/write operation on state (which is by design time consuming operation)

Serialization Mechanism


Serialization is a mechanism by which you can save the state of an object by converting it to a byte stream.The class whose instances are to be serialized should implement an interface Serializable. Then you pass the instance to the ObjectOutputStream which is connected to a FileOutputStream. This will save the object to a file.

The serializable interface is an empty interface. The class should implement Externalizable interface. This interface contains two methods namely readExternal and writeExternal. You should implement these methods and write the logic for customizing the serialization process.

The serialization mechanism generates an object graph for serialization. Thus it determines whether the included object references are serializable or not. This is a recursive process. Thus when an object is serialized, all the included objects are also serialized along with the original object.One should make sure that all the included objects are also serializable. If any of the objects is not serializable then it throws a NotSerializableException.

There are three exceptions in which serialization doesnot necessarily read and write to the stream. These are

  • Serialization ignores static fields, because they are not part of any particular state.
  • Base class fields are only handled if the base class itself is serializable.
  • Transient fields.

decimal to binary/octa/hexadecimal conversion

Here decimal to binary/octa/hexa decimal conversions are shown.

Algorithm is simple provided we should make use of the stack (stack implementation) to put the coefficients.

public class DecimalConversion {
	TNStack st = new TNStack(30);
	private static HashMap<Integer, String> hm = new HashMap<Integer, String>();
	
	/**
	 * converts number to given base
	 * @param number
	 * @param base
	 */
	public void decimalToXXXConversion(int number, int base) {
		System.out.println("Number "+number+" in base "+base+" is: ");
		while(number>0) {
			st.push(number%base);
			number = number/base;
		}
		
		while(!st.isEmpty()) {
			int n = st.pop();
			if(n>9) {
				String str = hm.get(n);
				System.out.print(str);
			} else {
				System.out.print(n);
			}
		}
		System.out.println();
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		DecimalConversion dc = new DecimalConversion();
	
		// decimal to binary conversion
		dc.decimalToXXXConversion(100, 2);

		// decimal to octal conversion
		dc.decimalToXXXConversion(100, 8);
				
		// decimal to hexadecimal conversion
		hm.put(10, "A");
		hm.put(11, "B");
		hm.put(12, "C");
		hm.put(13, "D");
		hm.put(14, "E");
		hm.put(15, "F");
		dc.decimalToXXXConversion(10012, 16);	
	}
}

Output:
Number 100 in base 2 is:
1100100
Number 100 in base 8 is:
144
Number 10012 in base 16 is:
271C

Queue implementation in Java

Queues operate in FIFO model.

Queues are also used in various other data structures, some of them are

  • searching graphs
  • printer queues in our machines
  • keystroke data that is typed onto the keyboard

Efficiency of queue is that it performs insert and remove operations in O(1) complexity.

package algorithm.queue;

/**
 * @author ntallapa
 *
 */
public class TNQueue {
	private int size;
	private int[] queueArr;
	private int front = -1;
	private int rear = -1;
	private int totalItems;

	public TNQueue(int s) {
		size = s;
		queueArr = new int[s];
	}

	public void insert(int i) {
		rear++;
		System.out.println("Inserting "+i);
		queueArr[rear] = i;
		totalItems++;
	}

	public int remove() {
		front++;
		totalItems--;
		System.out.println("Removing "+queueArr[front]);
		return queueArr[front];
	}

	public boolean isFull() {
		return (totalItems == size);
	}

	public boolean isEmpty() {
		return (totalItems == 0);
	}
}

package algorithm.queue;
/**
 * @author ntallapa
 *
 */
public class TNQueueClient {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		TNQueue tnq = new TNQueue(3);
		if(!tnq.isFull())
			tnq.insert(1);
		if(!tnq.isFull())
			tnq.insert(2);
		if(!tnq.isFull())
			tnq.insert(3);
		if(!tnq.isFull())
			tnq.insert(4);
		else
			System.out.println("Queue is full, cannot insert element");

		if(!tnq.isEmpty())
			tnq.remove();
		if(!tnq.isEmpty())
			tnq.remove();
		if(!tnq.isEmpty())
			tnq.remove();
		if(!tnq.isEmpty())
			tnq.remove();
		else
			System.out.println("Queue is empty, cannot remove element");
	}
}

Output:
Inserting 1
Inserting 2
Inserting 3
Queue is full, cannot insert element
Removing 1
Removing 2
Removing 3
Queue is empty, cannot remove element

Stack implementation in Java

Stacks operate in LIFO model.

Stack plays vital role in many data structures, some of them are

  • in parsing arithmetic expressions
  • to help traverse nodes of binary tree
  • searching vertices of a graph
  • in java, every method’s return type and arguments are pushed on to a stack and when method returns they are popped off.

Efficiency of stack is that it performs push and pop operations in O(1) complexity.

package algorithm.stack;
/**
 * @author ntallapa
 *
 */
public class TNStack {
	private int size;
	private int[] stackArr;
	private int top = -1;
	
	public TNStack(int size) {
		this.size = size;
		stackArr = new int[size];
	}
	
	/**
	 * increment the ctr and push element into stack 
	 * @param i element to be pushed
	 */
	public void push(int i) {
		top++;
		System.out.println("Pushing "+i);
		stackArr[top] = i;
	}
	
	/**
	 * pop the element from stack and decrement the ctr 
	 * @return the popped element
	 */
	public int pop() {
		int i = stackArr[top];
		top--;
		System.out.println("Popping "+i);
		return i;
	}
	
	public int peek() {
		System.out.println("Peek "+stackArr[top]);
		return stackArr[top];
	}
	
	public boolean isFull() {
		return (top == size-1);
	}
	
	public boolean isEmpty() {
		return (top == -1);
	}
}

package algorithm.stack;
/**
 * @author ntallapa
 *
 */
public class TNStackClient {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		TNStack tns = new TNStack(3);
		// push some elements
		if(!tns.isFull())
			tns.push(4);
		if(!tns.isFull())
			tns.push(5);
		if(!tns.isFull())
			tns.push(3);
		if(!tns.isFull())
			tns.push(6);
		else 
			System.out.println("Stack is full, cannot push element");
		
		// pop some elements
		if(!tns.isEmpty())
			tns.pop();
		if(!tns.isEmpty())
			tns.pop();
		if(!tns.isEmpty())
			tns.pop();
		if(!tns.isEmpty())
			tns.pop();
		else 
			System.out.println("Stack is empty, cannot pop element");
		
		//reinsert to verify peek method
		if(!tns.isFull())
			tns.push(6);
		
		// peek couple of times; result should be same
		tns.peek();
		tns.peek();
	}
}

Output:
Pushing 4
Pushing 5
Pushing 3
Stack is full, cannot push element
Popping 3
Popping 5
Popping 4
Stack is empty, cannot pop element
Pushing 6
Peek 6
Peek 6

Creating our own hashmap in java

This is an attempt to come up with my own hashmap in java. It serves all basic needs of original java.util.HashMap with O(1) complexity in read operations. Full source code can be downloaded from here

To deep dive into the fundamentals of java.util.HashMap refer to this article

STEP1: Create a simple data structure with key, value and which can also extend as linked list

  • line #2,#3: references to key and value
  • line #4: link to itself (used when there is collision in the hashmap)
    class Entry {
    	Employee key;
        String value;
        Entry next;
 
        Entry(Employee k, String v) {
            key = k;
            value = v;
        }
 
        public String getValue() {
            return value;
        }
 
        public void setValue(String value) {
            this.value = value;
        }
 
        public Employee getKey() {
            return key;
        }
    }

STEP2: Couple of important utility methods

  • getSupplementalHash(): Supplemental hash function used to defend against the poor quality hash given by the user
  • getBucketNumber(): It makes sure the bucket number falls within the size of the hashmap based on the value of hash
    private int getSupplementalHash(int h) {
		// This function ensures that hashCodes that differ only by
		// constant multiples at each bit position have a bounded
		// number of collisions (approximately 8 at default load factor).
		h ^= (h >>> 20) ^ (h >>> 12);
		return h ^ (h >>> 7) ^ (h >>> 4);
	}
    
    private int getBucketNumber(int hash) {
		return hash & (SIZE - 1);
	}

STEP3: PUT Method

  • line #3: get the user defined hashcode
  • line #4: defend against the poor quality hash functions defined by the user (if Employee.hashcode() is poor, this call will do a better job)
  • line #8: get the bucket index
  • line #12: If the control reaches into for loop, it means that it should either be a duplicate or a collision
  • line #14-15: Its a duplicate, it will be replaced with old one
  • line #20: Its a collision, new pair will be appended to the list
  • line #28: Its either a new_pair/collision, add it to the map
    public void put(Employee key, String value) {
		// get the hashcode and regenerate it to be optimum
		int userHash = key.hashCode();
		int hash = getSupplementalHash(userHash);

		// compute the bucket number (0-15 based on our default size)
		// this always results in a number between 0-15
		int bucket = getBucketNumber(hash);
		Entry existingElement = table[bucket];

		for (; existingElement != null; existingElement = existingElement.next) {

			if (existingElement.key.equals(key)) {
				System.out
						.println("duplicate key value pair, replacing existing key "
								+ key + ", with value " + value);
				existingElement.value = value;
				return;
			} else {
				System.out.println("Collision detected for key " + key
						+ ", adding element to the existing bucket");

			}
		}

		//
		System.out.println("PUT adding key:" + key + ", value:" + value
				+ " to the list");
		Entry entryInOldBucket = new Entry(key, value);
		entryInOldBucket.next = table[bucket];
		table[bucket] = entryInOldBucket;
	}

STEP4: GET Method

  • line #3: defend against the poor quality hash functions defined by the user (if Employee.hashcode() is poor, this call will do a better job)
  • line #7: get the bucket index
  • line #14: This loop is iterated as many times as the number of collisions for every key
  • line #23: If nothing is found
    public Entry get(Employee key) {
		// get the hashcode and regenerate it to be optimum
		int hash = getSupplementalHash(key.hashCode());

		// compute the bucket number (0-15 based on our default size)
		// this always results in a number between 0-15
		int bucket = getBucketNumber(hash);

		// get the element at the above bucket if it exists
		Entry existingElement = table[bucket];

		// if bucket is found then traverse through the linked list and
		// see if element is present
		while (existingElement != null) {
			System.out
					.println("Traversing the list inside the bucket for the key "
							+ existingElement.getKey());
			if (existingElement.key.equals(key)) {
				return existingElement;
			}
			existingElement = existingElement.next;
		}

		// if nothing is found then return null
		return null;
	}

STEP5: Employee object as the key to our custom map (TESTING)
hashCode(): Make sure the hash code falls with 0-10 so that we can reproduce collision easily.
equals(): based on id and name of the person

	static class Employee {
		private Integer id;
		private String name;

		Employee(Integer id, String name) {
			this.id = id;
			this.name = name;
		}

		@Override
		public int hashCode() {
			// this ensures all hashcodes are between 0 and 15
			return id % 10;
		}

		@Override
		public boolean equals(Object obj) {
			Employee otherEmp = (Employee) obj;
			return this.name.equals(otherEmp.name);
		}

		@Override
		public String toString() {
			return this.id + "-" + name;
		}
	}

STEP6: Test Code

  • line #13-14: Demonstrate duplicate key replacement in hashmap
  • line #30-42 and #31-35: Demonstrate collision in hashmap
  • line #44-49: Demonstrate collision along with duplication in hashmap
		TMHashMap tmhm = new TMHashMap();

		System.out.println("============== Adding Element ===================");
		Employee e1 = new Employee(100, "Niranjan");
		tmhm.put(e1, "dept1");

		// duplicate
		System.out.println("============== Adding Duplicate =================");
		Employee e1_dup = new Employee(100, "Niranjan");
		tmhm.put(e1_dup, "dept12");
		// the above value "dept12" should replace the old value "dept1"
		Entry e = tmhm.get(e1_dup);
		System.out.println("GET element - " + e.getKey() + "::" + e.getValue());

		System.out.println("============== Adding Elements ==================");
		Employee e2 = new Employee(102, "Sravan");
		tmhm.put(e2, "dept3");

		Employee e3 = new Employee(104, "Ananth");
		tmhm.put(e3, "dept2");

		Employee e4 = new Employee(106, "Rakesh");
		tmhm.put(e4, "dept5");

		Employee e5 = new Employee(108, "Shashi");
		tmhm.put(e5, "dept2");

		// collision with e2
		System.out.println("============== Adding Collisions =================");
		Employee e2_collision = new Employee(112, "Chandu");
		tmhm.put(e2_collision, "dept16");
		e = tmhm.get(e2_collision);
		System.out.println("GET element - " + e.getKey() + "::" + e.getValue());

		// collision with e3
		Employee e3_collision = new Employee(114, "Santhosh");
		tmhm.put(e3_collision, "dept9");
		e = tmhm.get(e3_collision);
		System.out.println("GET element - " + e.getKey() + "::" + e.getValue());

		System.out
				.println("============== Adding Duplicate in Collision ===================");
		Employee e3_collision_dupe = new Employee(124, "Santhosh");
		tmhm.put(e3_collision_dupe, "dept91");
		e = tmhm.get(e3_collision_dupe);
		System.out.println("GET element - " + e.getKey() + "::" + e.getValue());

OUTPUT: of this program

============== Adding Element ===================
PUT adding key:100-Niranjan, value:dept1 to the list
============== Adding Duplicate =================
duplicate key value pair, replacing existing key 100-Niranjan, with value dept12
Traversing the list inside the bucket for the key 100-Niranjan
GET element - 100-Niranjan::dept12
============== Adding Elements ==================
PUT adding key:102-Sravan, value:dept3 to the list
PUT adding key:104-Ananth, value:dept2 to the list
PUT adding key:106-Rakesh, value:dept5 to the list
PUT adding key:108-Shashi, value:dept2 to the list
============== Adding Collisions =================
Collision detected for key 112-Chandu, adding element to the existing bucket
PUT adding key:112-Chandu, value:dept16 to the list
Traversing the list inside the bucket for the key 112-Chandu
GET element - 112-Chandu::dept16
Collision detected for key 114-Santhosh, adding element to the existing bucket
PUT adding key:114-Santhosh, value:dept9 to the list
Traversing the list inside the bucket for the key 114-Santhosh
GET element - 114-Santhosh::dept9
============== Adding Duplicate in Collision ===================
duplicate key value pair, replacing existing key 124-Santhosh, with value dept91
Traversing the list inside the bucket for the key 114-Santhosh
GET element - 114-Santhosh::dept91

Full source code can be downloaded from here

After receiving a lot of requests/questions related to hashmap behavior on collisions and element duplication, I updated the code. I hope one can take it further from here 🙂

Towers of Hanoi Recursive Ananlysis

Recursive program to towers of hanoi problem

package algorithms.recursion;

/**
 * @author ntallapa
 *
 */
public class TowersOfHanoi {
	
	/**
	 * This recursive algorithm takes (2^n-1) iterations to complete the task
	 * 
	 * @param n number of disks
	 * @param startPole
	 * @param endPole
	 */
	public static void move(int n, int startPole, int endPole) {
		if (n== 0){
			return; 
		}
		// here 6 is summation of poles, i.e, sigma(3) = 3+2+1 = 6
		int intermediatePole = 6 - startPole - endPole;
		
		// Move n–1 disks from disk 1 to disk 2, using disk 3 as a temporary holding area.
		move(n-1, startPole, intermediatePole);
		
		// Move the last disk (the largest) from disk 1 to disk 3.
		System.out.println("Move " +n + " from " + startPole + " to " +endPole);
		
		//  Move n–1 disks from disk 2 to disk 3, using disk 1 as a temporary holding area.
		move(n-1, intermediatePole, endPole);
	}
	
	public static void main(String[] args) {
		move(4, 1, 3);
	}	
}

towersofhanoi

For 2 discs we need 3 iterations, 3 discs we need 7 iterations, 4 discs we need 15 iterations, etc… from this it can be realized that to move ‘n’ discs we need (2^n)-1 iterations.

Analysing Java Garbage Collector

Application Phases: Initialization → Steady state → Summary (optional)
– Initialization: startup, lots of allocations
– Steady state: where application spends the most time, running the ‘core’ part of the application
– Summary: produce report of what has happen, might be computationally intensive and maybe has lots of allocation as well
Note: Typically, the steady state is the most important

Performance
Three important performance attributes are throughput, latency, footprint
– Throughput – the percentage of time not spent on GC
– Latencies – the time when an app appears unresponsive because of GC
– Footprint – memory size
Note: Not all three are always important
– Usually select two of the three
– But you need to know what is important for your application

GC Logging
Yes even in production
– Very important, not just for testing, minimal overhead

Correlate application-level with GC/JVM level events
– GC not always to blame for long pauses
– Capture time/context sensitive events that might not be able to reproduce under testing

Flags

– -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:&lt;file&gt;
– -XX:+PrintGCDateStamps (from JDK6u4)
– -XX:+PrintHeapAtGC

GC Logging Output – 1

-XX:+PrintGCTimeStamps -XX:+PrintGCDetails
27.199: [Full GC (System)
[PSYoungGen: 81K-&gt;0K(26304K)]
[PSOldGen: 7497K-&gt;7559K(32256K)] 7579K-&gt;7559K(58560K)
[PSPermGen: 12166K-&gt;12166K(16384K)], <i>0.0495600 secs</i>]
[Times: user=<i>0.05 </i>sys=0.00, real=<i>0.04 secs</i>]
28.503: [GC
[PSYoungGen: 869K-&gt;64K(26304K)] 8429K-&gt;7623K(58560K),
0.0008190 secs]
[Times: user=0.00 sys=0.00, real=0.00 secs]

GC Logging Output – 2

-XX:+PrintGCDateStamps -XX:+PrintGCDetails
2011-04-25T10:55:50.007+0800: 9.140:
[GC [PSYoungGen: 8024K-&gt;1530K(26304K)] 15470K-&gt;10427K(58560K),
0.0023450 secs]
[Times: user=0.00 sys=0.00, real=0.01 secs]
2011-04-25T10:55:50.009+0800: 9.143:
[Full GC (System) [PSYoungGen: 1530K-&gt;0K(26304K)]
[PSOldGen: 8896K-&gt;7135K(32256K)] 10427K-&gt;7135K(58560K)
[PSPermGen: 11640K-&gt;11631K(23808K)], 0.0778080 secs]
[Times: user=0.12 sys=0.00, real=0.07 secs]

GC Logging Output – 3

-XX:+PrintGCHeapAtGC -Xloggc:&lt;file&gt;
{<b>Heap before GC invocations=20 (full 8)</b>:
PSYoungGen total 14144K, used 2287K [0xa3b90000, 0xa4b50000, 0xb3790000)
eden space 12160K, 18% used [0xa3b90000,0xa3dcbe00,0xa4770000)
from space 1984K, 0% used [0xa4770000,0xa4770000,0xa4960000)
to space 1984K, 0% used [0xa4960000,0xa4960000,0xa4b50000)
PSOldGen total 32256K, used 7465K [0x84390000, 0x86310000, 0xa3b90000)
object space 32256K, 23% used [0x84390000,0x84ada710,0x86310000)
PSPermGen total 19968K, used 11994K [0x80390000, 0x81710000, 0x84390000)
object space 19968K, 60% used [0x80390000,0x80f46bb0,0x81710000)
45.215: [GC 9753K-&gt;7538K(46400K), 0.0006110 secs]

Heap after GC invocations=20 (full 8):

PSYoungGen total 14144K, used 72K [0xa3b90000, 0xa4b50000, 0xb3790000)
eden space 12160K, 0% used [0xa3b90000,0xa3b90000,0xa4770000)
from space 1984K, 3% used [0xa4960000,0xa49723b0,0xa4b50000)
to space 1984K, 0% used [0xa4770000,0xa4770000,0xa4960000)
PSOldGen total 32256K, used 7465K [0x84390000, 0x86310000, 0xa3b90000)
object space 32256K, 23% used [0x84390000,0x84ada710,0x86310000)
PSPermGen total 19968K, used 11994K [0x80390000, 0x81710000, 0x84390000)
object space 19968K, 60% used [0x80390000,0x80f46bb0,0x81710000)
}

Choice of JVM
32-bit
– -d32 (default)
– For heap size up to 2.5G/3G

64-bit with/without compressed references
– -d64, -XX:+UseCompressedOops
– For heap size up to 26G or unlimited

32-bit to 64-bit migration
– Higher heap size requirement (approx 20%)
– Throughput impact (up to 20%, without compressed refs)

Mawazo

Mostly technology with occasional sprinkling of other random thoughts

amintabar

Amir Amintabar's personal page

101 Books

Reading my way through Time Magazine's 100 Greatest Novels since 1923 (plus Ulysses)

Seek, Plunnge and more...

My words, my world...

ARRM Foundation

Do not wait for leaders; do it alone, person to person - Mother Teresa

Executive Management

An unexamined life is not worth living – Socrates

Diabolical or Smart

Nitwit, Blubber, Oddment, Tweak !!

javaproffesionals

A topnotch WordPress.com site

thehandwritinganalyst

Just another WordPress.com site

coding algorithms

"An approximate answer to the right problem is worth a good deal more than an exact answer to an approximate problem." -- John Tukey