Skip to main content

Java puzzler

You'll need an understanding of weak references to have a meaningful stab at this one.


public class Test {

public static void main(String[] args) {
List<byte[]> list = new ArrayList<byte[]>();

Object thing = new Object();
WeakReference<Object> ref = new WeakReference<Object>(thing);

while(ref.get()!=null) {
list.add(new byte[10000]);
}
System.out.println("bam");
}

}


Before reading any further give it a stab, see what you come up with. Then run it and see. Oh and yes, it compiles and runs.






...







Well, there's two possible options that you could have sensibly come up with. The first is what most people assume will always happen - the byte array will fill up to cause an OutOfMemoryError and the weak reference will never be garbage collected because there also exists a strong reference (thing) that remains in scope throughout the application and thus doesn't "let go" of the object. And indeed if you run it with early versions of Java, this is exactly what will happen.

However, with the latest version of JDK7 (update 2 at the time of writing) the program doesn't do the above, it prints out "bam" and exits cleanly. This initially seems weird - there's still a strong reference in scope so why on earth is it garbage collected?

It boils down to improvements in the JIT. It realises that the hard reference isn't actually used again, so sets it to null thus making it eligible for garbage collection. Put something like "thing.getClass();" as the last line of the program and it always forces the OutOfMemoryError because if that's the case the JIT can't make this optimisation. It's a behaviour that's actually explicitly covered in the JLS:

Optimizing transformations of a program can be designed that reduce the number of objects that are reachable to be less than those which would naively be considered reachable. For example, a compiler or code generator may choose to set a variable or parameter that will no longer be used to null to cause the storage for such an object to be potentially reclaimable sooner.


http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.6.1

The lesson? Objects can be garbage collected when the JIT decides they're no longer in use, and this may be earlier when it seems - and this in turn means that finalizers can be called when the object might trivially seem in-scope and thus ineligible for collection.

Comments

Popular posts from this blog

Dropbox Java API

This code will no longer work! It uses the old v1 API, which has been turned off. See here for working code with the latest v2 API. As well as being useful as general cloud storage, dropbox also has an API that lets you access its contents programmatically. It's a straightforward REST API with a number of language specific libraries to make the going a bit easier. Java is included on the list of SDKs, but at present only Android is included on the list of tutorials. This can be somewhat frustrating because simple examples using Java are lacking. Fortunately, the process was described by Josh here . So I've taken it and implemented it in Java, and it seems to work. It's a very basic example that authenticates with dropbox then uploads a file called "testing.txt" containing "hello world." Of course, more functionality is available than this, but this is the hard part (at least I found working this bit out the hard part.) Once you've got your Dro...

The comprehensive (and free) DVD / Blu-ray ripping Guide!

Note: If you've read this guide already (or when you've read it) then going through all of it each time you want to rip something can be a bit of a pain, especially when you just need your memory jogging on one particular section. Because of that, I've put together a quick "cheat sheet" here  which acts as a handy reference just to jog your memory on each key step. I've seen a few guides around on ripping DVDs, but fewer for Blu-rays, and many miss what I believe are important steps (such as ensuring the correct foreign language subtitles are preserved!) While ripping your entire DVD collection would have seemed insane due to storage requirements even a few years ago, these days it can make perfect sense. This guide doesn't show you a one click approach that does all the work for you, it's much more of a manual process. But the benefits of putting a bit more effort in really do pay off - you get to use entirely free tools with no demo versions, it...

Using VLCJ for video reliably with out of process players

This post is really a follow on to the last, so if you want a bit of background give that a read through. In it I basically talk about the various options I came to when trying to implement video support in Java, and how I felt the best way to go was using out of process players and VLCJ. Before I get to the code, a warning - while this isn't stupidly hard, it's definitely not for beginners. If you're competent with Java in general you shouldn't have any trouble following - but this is not a cut / paste / forget the advanced stuff job! Eventually and depending on interest I may look into packaging it up into an easy to use library and distributing, but that day is not today! Secondly, this code is literally cut straight out of Quelea and at the moment is: Largely uncommented From an unreleased version Not the best quality May contain Quelea specific bits that don't apply Eventually, it'll all be refactored into beautiful OO-like niceness. But in terms of the con...