Skip to content

How much memory the java objects consume?

March 16, 2011

Recently I read the article to determine the size of java objects and found some interesting facts on object creation in java.

For an empty class:

public class TestClass {

}

size of the TestClass Object is 2 * Reference = 2*4 = 8 bytes.

For a class with primitive – int:

public class TestClass {
int i=0;
}

size = 2 * reference + size of int = 2*4 + 4 = 12 = 16 bytes (word aligned)

For a class with primitive – long:
public class TestClass {
long i=0;
}

size = 2 * reference + size of long= 2*4 + 8 = 16 bytes.

similarly for float and double , the size is 16 bytes.

Taking the wrapper classes,

public class TestClass {
Integer i= new Integer(0);
}
size = 2 * reference for TestClass Object + 2*Reference for Integer object  + size of int

= 2*4 + 2*4 + 4 = 32 bytes (word aligned)

Similarly the sizes for the objects with the Long, Float and Double fields are32 bytes.

Instead of using the ‘new’ key word for the Integer instantiation, if we use Integer i=1; then the results are different.

public class TestClass {
Integer i=0;
}

size = 5152 bytes.

The reason being Integer i=0; is inferred as Integer i= Integer.value(0);

A cache is initialized with all the possible int values varying from -128 to 127.  The ‘i’ is initialized with the value zero from the cache.

If you take the String instantiation,

public class TestClass {
String s=new String(“i”);
}

it consumes about 40 bytes of memory where as,

public class TestClass {
String s=”i”;
}

consumes about 16 bytes of memory. It took less bytes since “i” is from the string pool.

Restart windows from command prompt

April 16, 2010
tags: ,

> shutdown -r -f -t 04

Where,

-r is Restart

-s is for a straight Shutdown

-h is for Hibernate

-f is Force

-t is Timelapse with a 04 second delay.

If you want to abort the shutdown use…

> shutdown -a

OutOfMemoryErrors variants

April 13, 2010
tags:

One day or the other every java developer will come across the out of memory error. If you are lucky enough you will notice that in your dev boxes, otherwise you will get the attention by your management within overnight causing the application to crash.

OutOfMemory in Heap:

In the heap we get an OutOfMemoryError, if the garbage collector cannot reclaim enough memory for a new object. In such situation the Sun HotSpot JVM shows this error message:
Exception in thread “main”: java.lang.OutOfMemoryError: Java heap space

A alternative for this is

Exception in thread “main”: java.lang.OutOfMemoryError: Requested array size exceeds VM limit

if the application tries to create an array on the heap that is bigger than the total heap size.

OutOfMemory in Method Area:

If there is not enough memory in the method area for creating a new class, the Sun HotSpot implementation gets an error in the permanent generation:

Exception in thread “main”: java.lang.OutOfMemoryError: PermGen space

OutOfMemory in Threads:

OutOfMemory errors in thread exclusive memory areas occur less frequently and are identified by the following error messages in the Sun HotSpot JVM:

Exception in thread “main” java.lang.OutOfMemoryError: unable to create new native thread

Exception in thread “main”: java.lang.OutOfMemoryError: <reason> <stacktrace> (Native method)

The first error is thrown if there are too many threads in the JVM and there is not enough memory left to create a new thread. This is because the memory limits of a process have been reached or the maximum number of file handles for the user that executes the java process has been reached. The second error message indicates that a memory allocation error on a native stack (JNI method call) has occured.

It is also interesting that a memory allocation error on the JVM stack (too many frames on the stack) does not throw an Java OutOfMemory error but as the JVM specification mandates: java.lang.StackOverflowError.

The last variant of the OutOfMemoryError is

Exception in thread “main”: java.lang.OutOfMemoryError: request <size> bytes for <reason>. Out of swap space?

This error is thrown if there is not enough memory left on the operating system level – which is normally true if other processes are using all of the available memory or the swap space is configured too small.

In Successful Search of Bug

February 23, 2010
tags: ,

I have always enjoyed debugging rather than coding. This post is about some of the troubleshooting methods that I came across while debugging.

Debugging is locating the defects. In the book Debugging, David Agans formulates nine rules of debugging for successful search of a bug.

Understand the system.

Make it fail.

Quit thinking and look.

Divide and Conquer.

Change one thing at a time.

Keep an audit trail.

Check the plug.

Get a fresh view.

If you don’t fix it , it ain’t fixed.

You cannot locate the defects unless you are familiar with the system. Though it takes most of your time, it is worth doing it. You need the understanding of the finer details.

Reduce the problem to its essence. Determine the smallest input that will cause the bug. The simpler the data or path to the bug, the more easily you can deduce or track down the problem.

You must change the conditions of the test to see if your bug disappears. If you correct the bug with a change, that change might tell you what the problem is, or at least give you a big hint about what is going on. You form hypotheses with your logic and deductive reasoning skills and then filter them by experimentation and observation. For example, by experimentation, we concluded that the specific argument caused the problem. Finally, we narrowed it down (by using some experience) to the equals as escape problem.

Experience helps in the debugging process in two ways: first, you hone your ability to execute the previous four elements; and second, you might have seen a similar bug or just plain know more about a particular problem.

Designing for debugging by Andreas Zeller:

When it comes to testing and debugging, a model-view-controller architecture has several benefits.  For testing, one can build and add new controllers that invoke services of the model—for instance, controllers that automate execution of these services. For debugging, one can register special views that automatically log all changes to the model. Finally,every observer and model can be examined and tested in isolation, thus reducing complexity.

Debugging sessions:

Java bytecode – using system.out.println. Java Pitfalls by Michael C. Daconta shares a useful technique for applying the println() method. Daconta suggests creating a DebugManager() class that allows you to set a debug flag based on certain classes or applications.

Using comments – comment out larger part of code and narrow down the search.

Remote debugging -running an application on one computer and debugging it on another computer.

Debugging on demand -you open a debugging session whenever an unhandled exception or other unrecoverable error occurs in your program.

Compilation or syntactical errors are the first that you will encounter and the easiest to debug. They are usually the result of typing errors.

Logic errors are different from run-time errors because there are no exceptions thrown, but the output still does not appear as it should. These errors can range from buffer overflows to memory leaks.

Run-time errors occur during the execution of the program and typically generate Java exceptions.

Threading errors are the most difficult to replicate and track down.

Preparation for debugging:

If you use the javac compiler to build your code for debugging, use the -g compiler option.  You can still set breakpoints and step through your code if you do not compile your classes with the -g option; however, you will not be able to inspect variables. The -g option lets you include debugging information in compiled code. This is useful if you want to be able to run the java debugger (jdb).

Keep in mind that if you compile with the -O option that optimizes your code, you will not be able to debug your classes. Optimization will remove all debugging information from the class.

You can manually force the generation of a stack trace using either the following statements.

* Throwable().printStackTrace() to generate a trace of the method’s code at a single point in time. The trace will show the method’s calls across threads.

* Thread.currentThread.dumpStack() to generate a snapshot of the current thread only.

Diagnostic methods:

The Java language provides methods from the Runtime() class to trace the calls you make to the Java virtual machine.

Turn on tracing will produce a list of every method call your program makes:

traceMethodCalls(true)

Turn off tracing by adding the following line to your source code:

traceMethodCalls(false)

Of the all, log files are the best sources of debugging. If you practice debugging through logs, its of much useful in troubleshooting production issues where you are provided with none other than logs. Logging statements serve no other purpose than debugging,they do not help us in understanding the code.The main message a logging statement conveys is that the procedure in question was in need of debugging. Therefore, logging is to be done with specific code locations, events and data. For performance reasons,output is typically buffered before actually being written to the output device. In the event of a program crash,this buffered output is lost. Using ordinary (buffered) output for logging thus hides what happened in the last few events before the crash. One can either use an unbuffered channel for logging (introducing a slowdown,as described previously) or make sure that the program flushes its buffered logs in case of a crash.

To Redirect Error Messages from Command Prompt

February 12, 2010
tags: ,

When redirecting output from an application using the “>” symbol, error messages still print to the screen.  This is because error messages are often sent to the Standard Error stream instead of the Standard Out stream.  To redirect STDERR  specify “2>”  by which the error messages are redirected to the specified channel

eg : javac SampleFile.java 2> compileerror.txt

The compilation errors are captured in the compileerror.txt file.

How to avoid “!= null” statements in Java?

January 28, 2010

One of the common problems that most developers tend to face at some point is defensively over checking for nulls. Many anticipate the null response without trusting the contract and bloat the code with !=null conditions making it unreadable and ugly.  Often times a method needs to return a value or nothing depending on its internal and working state.  Here nothing includes the null value too which means returning a null value is a valid one by contract.

To be precise, we have two options in getting the response

i. null is not allowed

ii. null is allowed

option i is easy to handle. If null  is not allowed,

Use assert and throw an error stating it. The JRE is configured by default to ignore the asserts. By using the option -esa (enablesystemassertions), one can enable asserts to various levels like classes or packages.

option ii – null is allowed and if it is passed from external method, then one have to be careful in dealing with it. You have no choice other than using

if( value !=null)

doSomething()

else

doOtherthing();

Its one time checking. You are sure that value cannot be null for the rest of the program and you are free to use the variable in subsequent methods without any block to check for null conditions.

On the other way, if you have control over the external method, then you can force the method to return empty string or empty collections instead of null as described in NULL OBJECT pattern.

The Null Object says,  “Just because I don’t have anything and don’t do anything, it does not mean that I am not smart.  By not having anything, I don’t take up much resource and can be shared among many.  By not doing anything, I am doing the right thing.”



Martin Fowler claims Nulls are awkward things and comes up with this particular refactoring pattern.

“Instead of returning null, or some odd value, return a Special Case that has the same interface as what the caller expects.”

Java has proposed for the null type annotation in JSR 305 and the proposal has some contradictions  described here.

Null-ignore invocation and Null safe types are another proposals similar in some ways to the JSR 305/308 annotation proposal for annotating whether parameters may or may not be null.

Proposals can be viewed at  Null-ignore invocation, Null-safe types

Null-ignore invocation is concerned with dealing with possible null values in calling one or especially a chain of methods.

For example, instead of

public String getPostcode(Person person) {
if (person != null) {
Address address = person.getAddress();
if (address != null) {
return address.getPostcode();
}
}
return null;
}

you could instead call:

public String getPostcode(Person person) {
return person?.getAddress()?.getPostcode();
}

Another issue concerns how to handle common if-null scenarios with a shortened form of the ternary operator specific to nulls. So rather than:

String str = getStringMayBeNull();
str = (str == null ? “” : str);

you might do:

String str = getStringMayBeNull() ?: “”;

This proposal moves checking of nulls from run-time to compile-time which will avoid many NullPointerExceptions and increase the robustness of Java programs.

Encapsulation is not Information Hiding

January 4, 2010
tags: ,

Encapsulation is  often mistook for information hiding. Though they are used interchangeably many a times, they do not synonym with each other.

Grady Booch says (in Object Oriented Analysis and Design, page 49, second edition):

“Abstraction and encapsulation are complementary concepts: abstraction focuses on the observable behavior of an object… encapsulation focuses upon the implementation that gives rise to this behavior… encapsulation is most often achieved through information hiding, which is the process of hiding all of the secrets of object that do not contribute to its essential characteristics.”

Encapsulation is wrapping data and functions that operate on that data inside an object where as information hiding is hiding internal details of the object.

class MyApp{
 public float calculateArea(Square sqr){
 return sqr.getSide()*sqr.getSide();
  }
 }

class Square(){
private float side;
 public float getSide(){
 return side;
  }
 }

The area is calculated by side * side and it is specific to the Class Square. Hence the implementation of getArea  should be within the class  Square which is Encapsulation and the method of how to  calculate the area of the square should not be exposed to the external class which is Information Hiding.

class MyApp{
 public float calculateArea(Square sqr){
 return sqr.getArea();
  }
 }

class Square(){
private float side;
 public float getSide(){
 return side;
  }

public float getArea(Square sqr){
 return sqr.getSide()*sqr.getSide();
  }
 }

Wrapping of data and functions doesn’t mean that creating public properties for each field and all fields are to be made private. The getter and setter methods are to be selected carefully. Expose only the properties that will be accessed by others.

Neal Ford in ‘The productive Programmer’ explains how to choose the properties in ‘Breaking Encapsulation’.

1. Create properties only when you need them. It avoids the unnecessary coding and code bloating. Also you don’t have to  unit test that property since it is always called from other code.

2.Create atomic mutator instead of creating public properties for each field.

He substantiates it with the below one.

c = Calendar.getInstance();
c.set(Calendar.MONTH, Calendar.FEBRUARY);
c.set(Calendar.DATE, 31);
System.out.println(c.get(Calendar.MONTH));
System.out.println(c.get(Calendar.DATE));

It would print 2 and 3.  The problem is, because Calendar is not aware of its state and its ability to set individual properties separately. It cannot be made atomic since it keeps track of time too. Since Calendar has too many responsibilities its behavior is uncertain.

“Instead of blindly creating properties when you create a new class, here is an alternative strategy: create properties only when you need to call them from other code. This serves several
purposes. First, you don’t have any code you don’t actually need. Developers create far too much speculative code because they think “I’m sure I’ll need that later, might as well create it
now.” Because you are letting the tool create properties for you anyway, it’s no more work to create them as you need them than to create them up front. Second, you cut down on needless
code bloat. Properties take up lots of space in source files, and reading through all that boilerplate code slows you down. Third, you don’t have to worry about writing unit tests for
your properties. Because you are always calling them from some other method that utilizes the property, they will automatically get code coverage in your tests. I never do test-driven
development for properties (get/set methods in Java, properties in C#); instead, I allow them to come into being only when there is a real need.”

Sriram ensures that Encapsulating an object is not about protecting (or securing) the said object. If you must think in terms of protection, then it is about protecting the consumers (callers) of the object. Encapsulation is about freeing your consumers from the knowledge of your implementation details. By doing so, you insulate your consumers from any ripple effect of changes to your implementation.

Hence, a careful distinction between encapsulating and hiding the behavior is to be made during design decisions since it is harder to realise when the decision is incorrect.

  • Information hiding conceals how an object implements its functionality and the designer  is free to change its functionality without the knowledge of the external modules.
  • Encapsulation tells about that the behaviour of an object ie, the state of an object and the methods that work on them.

Follow

Get every new post delivered to your Inbox.