Test size of your data structures in Unit Test

Petr Nejedly invented interesting tool for measuring memory usage of data structures on java heap. Name of the tool is Insane. Pages of the tools are here. It uses Java introspection to traverse all fields and references in graph of data structure. It allows to exclude traversing for specified references. Insane was integrated with NBJunit library. NBJunit is extension of Junit 3.x. It was designed in order to test NetBeans IDE. In this article I try show power of Insane library inside NBJunit.

NBTestCase class is supper class of for NetBeans test. It extends from Junit TestCase. The NBTestCase contains assertSize methods for testing size of java structures. For example we want to measure size of NumList class:

    public static class NumList {
        public int num;
        public NumList next;
    };

A instance of the class takes 16 bytes on the heap on 32bit virtual machine. A simple test for this structure can look like this:

  public void testA() {
        NumList item = new NumList();
        // 1. test one instance   
        assertSize("NumList a",16,item);
        // 2. test size of instances in collection 
        assertSize("NumList a",Collections.singleton(item),16);
        NumList item2 = new NumList();
        item.next = item2; 
        // 3. test linked structure 
        assertSize("NumList a",Collections.singleton(item),32);
        // 4. ignore the item2 references
        assertSize("NumList a",Collections.singleton(item),16,new Object[]{item2});
    }

The test passed when the size of the structure doesn't exceed the defined limit (16 or 32 bytes). Interesting is use case on line number four

assertSize("NumList a",Collections.singleton(item),16,new Object[]{item2});

The last parameter tells that the measurement won't traverse through item2 reference. It is very useful when we measure only subset of complicated structure.

The test passed. Why the instance of NumList takes 16 bytes in memory of 32bit JVM?

  • 8 bytes are for object header
  • 4 bytes are allocated for num variable
  • 4 bytes are allocated for reference to next NumList
We can start to experiment with our structure. We add one field to NumList class:

    public static class NumList {
        public int num;
        public int num2;
        public NumList next;
    };

We run the test again. The test fails with message:

Testcase: testA(MemoryTest):	FAILED
NumList a: leak 8 bytes  over limit of 16 bytes
  MemoryTest$NumList: 1, 24B

junit.framework.AssertionFailedError: NumList a: leak 8 bytes  over limit of 16 bytes
  MemoryTest$NumList: 1, 24B

        at org.netbeans.junit.NbTestCase.assertSize(NbTestCase.java:1108)
        at org.netbeans.junit.NbTestCase.assertSize(NbTestCase.java:1065)
        at org.netbeans.junit.NbTestCase.assertSize(NbTestCase.java:1050)
        at org.netbeans.junit.NbTestCase.assertSize(NbTestCase.java:1039)
        at MemoryTest.testA(MemoryTest.java:28)
 

Instance takes 24 bytes in memory now. How is it possible if the int type tales 4 bytes in memory? Yes it takes four bytes. The instance takes 24 bytes on heap because the size of java object is aligned to 8 bytes. So we will fix the test for new NumList version.

  public void testA() {
        NumList item = new NumList();  
        assertSize("NumList a",24,item);
        assertSize("NumList a",Collections.singleton(item),24);
        NumList item2 = new NumList();
        item.next = item2; 
        assertSize("NumList a",Collections.singleton(item),48);
        assertSize("NumList a",Collections.singleton(item),24,new Object[]{item2});
       
    }

The test passed now. The instance is aligned to 8 bytes as I wrote. Why to no try add one more varible to TestNum structure? The new version is below.

    public static class NumList {
        public int num;
        public int num2;
        public int num3;
        public NumList next;
    };

This version does't need more memory than the previous. We can check it by running the test. Yes, the test passed now. Isn't combination of Insane ane NbJUnit great idea?

Comments:

Post a Comment:
Comments are closed for this entry.
About

xzajo

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today