Monday, December 28, 2009

Using Closeable Interface


static void copy(String src, String dest) throws IOException {
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(src);
out = new FileOutputStream(dest);
byte[] buf = new byte[1024];
int n;
while ((n = in.read(buf)) >= 0)
out.write(buf, 0, n);
} finally {
if (in != null) in.close();
if (out != null) out.close();
}
}



The stream fields (in and out) are initialized to null and set to the new streams as soon as they are created. The finally block closes the stream referred to by each field if it is non-null. An error during the copy would cause an IOException, but the finally block would still execute before the method returns. What could go wrong?

Yes...
The problem resides in finally block
The close method can throw an IOException too. If this happens when in.close is called, the exception prevents out.close from getting called, and the output stream remains open.

The solution would be to wrap each call to close in a nested try block

} finally {

if (in != null) {

try {

in.close();

} catch (IOException ex) {

// There is nothing we can do if close fails

}

}



if (out != null) {

try {

out.close();

} catch (IOException ex) {

// Again, there is nothing we can do if close fails

}

}

}



Closeable interface comes to your rescue, helping you to abstract it at one routine
like this


} finally {

closeIgnoringException(in);

closeIgnoringException(out);

}



private static void closeIgnoringException(Closeable c) {

if (c != null) {

try {

c.close();

} catch (IOException ex) {

// ignore if you dont have any thing to do here
}

}

}


And finally

A Closeable is a source or destination of data that can be closed. The close method is invoked to release resources that the object is holding.

Wednesday, December 16, 2009

PermGen space

The memory in the Virtual Machine is divided into a number of regions. One of these regions is PermGen. It's an area of memory that is used to (among other things) load class files. The size of this memory region is fixed, i.e. it does not change when the VM is running. You can specify the size of this region with a commandline switch: -XX:MaxPermSize . The default is 64 Mb on the Sun VMs.

If there's a problem with garbage collecting classes and if you keep loading new classes, the VM will run out of space in that memory region, even if there's plenty of memory available on the heap. Setting the -Xmx parameter will not help: this parameter only specifies the size of the total heap and does not affect the size of the PermGen region.

Free up log4j memory usage at context unload

public class ApplicationLifecycleListener implements ServletContextListener{
public void contextDestroyed(final ServletContextEvent sce) {
LogFactory.release(Thread.currentThread().getContextClassLoader());
}
public void contextInitialized(final ServletContextEvent sce)
{}
}

NIO- New I/O

The new I/O (NIO) classes added in Java 1.4 introduced a new way of performing I/O based on channels and buffers.
As well as I/O buffers backed by memory on the Java heap, NIO added support for direct ByteBuffers (allocated using the java.nio.ByteBuffer.allocateDirect() method) that are backed by native memory rather than Java heap. DirectByteBuffers can be passed directly to native OS library functions for performing I/O — making them significantly faster in some scenarios because they can avoid copying data between Java heap and native heap.
It's easy to become confused about where direct ByteBuffer data is being stored. The application still uses an object on the Java heap to orchestrate I/O operations, but the buffer that holds the data is held in native memory — the Java heap object only contains a reference to the native heap buffer. A non-direct ByteBuffer holds its data in a byte[] array on the Java heap. Figure 4 shows the difference between direct and non-direct ByteBuffer objects:


Direct ByteBuffer objects clean up their native buffers automatically but can only do so as part of Java heap GC — so they do not automatically respond to pressure on the native heap. GC occurs only when the Java heap becomes so full it can't service a heap-allocation request or if the Java application explicitly requests it (not recommended because it causes performance problems).
The pathological case would be that the native heap becomes full and one or more direct ByteBuffers are eligible for GC (and could be freed to make some space on the native heap), but the Java heap is mostly empty so GC doesn't occur.

Semantic Versioning Specs

1> Software using Semantic Versioning must declare a public API. This API could be declared in the code itself or exist strictly in documentation. However it is done, it should be precise and comprehensive.
2> A version number takes the form X.Y.Z where X, Y, and Z are integers. X is the major version, Y is the minor version, and Z is the patch version. Each element increases numerically such that version 1.0.10 follows 1.0.9.

3> When tagging releases in a version control system, the tag for a version MUST be "vX.Y.Z" e.g. "v3.1.0".
4> Once a versioned package has been released, the contents of that version MUST never be modified. Any modifications MUST be released as a new version.
5> Major version zero (0.y.z) is for initial development. Anything may change at any time. The public API should not be considered stable.
6> Version 1.0.0 defines the public API. The way in which the version number is incremented is now dependent on this public API and how it changes.
7> Patch version Z (x.y.Z x > 0) MUST be incremented if only backwards compatible bug fixes are introduced. A bug fix is defined as an internal change that fixes incorrect behavior.
8> Minor version Y (x.Y.z x > 0) MUST be incremented if new, backwards compatible functionality is introduced to the public API. It MAY be incremented if substantial new functionality or improvements are introduced within the private code. It MAY include patch level changes.
9> Major version X (X.y.z X > 0) MUST be incremented if any backwards incompatible changes are introduced to the public API. It MAY include minor and patch level changes.