How much memory the java objects consume?
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
> 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
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
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.
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
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?
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.
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
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.
To Throw or to Catch exceptions in JUnit
What would happen if an exception is thrown from the test method? Obviously the test would fail. Getting an exception is not the workflow of the code and hence the test should fail.
public void testMethod() throws checkedException{
assertEqauls(true,someMethod());
}
What if the exception is expected for a particular use case of the code. Here, getting an exception is an expected one and we don’t want the test to fail. So,we catch the exception in the try/ catch block and make the test case to win.
public void testMethod(){
try{
assertEquals(true, someOtherMethod());
fail(“Should get an Exception”);
}catch(ExpectedException e){
}
}
The above test case can be modified for the unchecked expected exception as
@Test(expected=unCheckedExpectedException.class)
public void testMethod(){
assertEquals(true,someOtherMethod());
}
Catch the exceptions only when we want the code to throw the exceptions as per the api contract. In all other cases, throw the exceptions – all the checked exceptions , in the throws clause of the test method and not catch the unchecked or runtime exceptions. Let the exceptions perk up and the JUnit framework would take care of it by making the test case a failed one.
What to do when an exception occurs in the set up / tear down methods?
Getting an exception in the setUp method makes the execution to halt with failure without calling the tearDown method and thus, giving us two problems. First, if the test case constructor uses the setUp method, then we are clueless to get the underlying exception cause. Second, if a resource is initialized in the setUp method before an exception, it becomes a leaking resource as the tearDown method would never be called.
With the exception in tearDown method, the JUnit framework hides the other uncaught exceptions from the test methods and displays the exception from the tearDown method with the test error. Hence the exceptions from the tearDown methods are to be caught and handled properly.
To turn off Ballon tip notifications
1. Run regedit.
2. Look for HKEY_CURRENT_USER \Software\Microsoft\Windows\CurrentVersion
\Explorer\Advanced.
3. Create a DWORD value (or edit it if it already exists) named EnableBalloonTips with value zero.
4. Log off and log in again.
Ref:
the productive programmer – by Neal Ford
Singletons : Is Anti-Pattern?
This was one of the long pending topic that stroked me when I was trying to create a Singleton class sometime back. What I wanted to have was a cache manager - A CacheManager which holds all the name value pairs that were globally used by the application. So I decided to use Singleton since I would like to have global access to the NV pairs and also I would like to maintain a single instance of the class. I made sure that it worked with “Initialization on Demand Holder” (lazy initialization) .
public class CacheManager {
private static final CacheManager m_instance = null;
public static CacheManager getInstance() {
if(m_instance==null)
synchronized(CacheManager.Class){
if(m_instance==null)
m_instance=new CacheManager();
}
return m_instance;
}
private CacheManager() {
//empty
}
}
Was double checking done? yes, done. Was synchronized used? yes, used. Was ‘synchronized’ blocking the entire method and making the method costly? No, the code was blocked only when the object was created. Fine. I was happy with the CacheManager.
It worked well for sometime and showed its bad face when multiple threads were involved. I found that Double-checked locking was not guaranteed to work in multi threaded environment-“Double checked locking is broken-declaration”
To make it work under multiple threads, I gave up the lazy loaded feature. What if the CacheManager was initialized and was never used, the code would work insanely. It was the pay for the thread safe implementation.
public class CacheManager{
private CacheManager() {}
private static class CacheHolder {
private static CacheManager instance = new CacheManager();
}
public static Singleton getInstance() {
return CacheHolder.instance;
}
}
Then I learned from here that, Singletons is a lie – there can be more than one instance of Singleton classes.
“When copies of the Singleton class run in multiple VMs, an instance is created for each machine.”
“When two class loaders load a class, you actually have two copies of the class, and each one can have its own Singleton instance.”
“Copies of a Singleton Object that has Undergone Serialization and Deserialization.”
Singletons cheat us from design perspective too - here, here and here.
It violates the OO concepts of Single Responsiblity Principle - Singleton enforces the instance policy and provides the access to configuration.
There is no way to subtype the Singleton class as the initialization cannot be overridden and there are static methods in it.
Singleton makes the unit testing harder as there is no way to mock it.
It maintains its state throughout the application and Persistent states are hard to test.
Singleton hide the dependencies and make the classes tightly coupled with each other.
Singletons are acceptable in few cases and there are some “cleaner” ways of achieving singleton benefits. Here, Misko clearly points that Singletons are useful when there is one way flow in the application.
“Logging is perfect example. It is loaded with Singletons and global state. It is acceptable (as in it will not hurt you) because your application does not behave any different whether or not a given logger is enabled. The information here flows one way: From your application into the logger. Even thought loggers are global state since no information flows from loggers into your application, loggers are acceptable. You should still inject your logger if you want your test to assert that something is getting logged, but in general Loggers are not harmful despite being full of state.”
So,
1. Don’t use Singletons for its “GLOBAL STATE”
2. Use Singletons as STATELESS Object or as IMMUTABLE objects.
3. Use Singletons by dependency injection and make it loosely coupled with others.
