Sunday 29 July 2012

A neat tool for detecting Memory Leaks from within a Unit Test (Java)


On the train back from work today I crafted an implementation of a HashWheel (a very cool algorithm for scheduling work), and while planning my unit tests I wanted to know that when a task had fired or been cancelled that the HashWheel released the job. Ala no memory leak. So I knocked up the following few lines that I thought were cool enough to share. The best bit was; it found a memory leak that I had missed straight away! Result! :)

I also added it to a github repository where you can find the full source code, take a look at TestTools.java under the public github repository threadtesting-mosaic.


The tool waits for up to three seconds (usually less than 40 milliseconds on my laptop; if it is going to pass that is) before throwing an exception.

To use the tool, just instantiate WeakReference and call TestTools.spinUntilReleased( ref ).

    public static void spinUntilReleased( final Reference ref ) {
        Runtime.getRuntime().gc();

        spinUntilTrue( new Predicate() {
            public boolean eval() {
                return ref.get() == null;
            }
        });
    }

Here is an example unit test that makes use of this tool:

    @Test
    public void scheduleTask_cancelViaTicketAndLetGoOfTask_expectTaskToBeGCd() {
        MyTask task1 = new MyTask();

        HashWheel.Ticket ticket = hashWheel.register( 120, task1 );
        ticket.cancel();

        final Reference ref = new WeakReference(task1 );
        task1 = null;

        TestTools.spinUntilReleased( ref );
    }

For completeness, here is the implementation of spinUntilTrue. Which can also be found in the threadtesting-mosaic repository.
    public static void spinUntilTrue( Predicate predicate ) {
        spinUntilTrue( 3000, predicate );
    }

    public static void spinUntilTrue( long timeoutMillis, Predicate predicate ) {
        long startMillis = System.currentTimeMillis();

        while ( !predicate.eval() ) {
            long durationMillis = System.currentTimeMillis() - startMillis;

            if ( durationMillis > timeoutMillis ) {
                throw new IllegalStateException( "Timeout" );
            }

            Thread.yield();
        }
    }

Sunday 22 July 2012

GitHub Work Culture (people change jobs because of burn out, how to prevent burn out while still working hard?)

A colleague pointed me at this little meme: http://vimeo.com/43676958

Most company work spaces would destroy what they have to say as dangerous, claiming that it would never work.  The interesting thing is that it does work for GitHub, and it works very well.

For me it reminds me of something a very good manager once taught me; the role of a manager is to create and protect the environment and culture for productive software development. It only takes one manager to ignore that advise to damage or destroy the soul of a work place and GitHub has pushed back hard against that decay in thought provoking ways.