Requirements
All inspectIT transfer objects (see Domain model) have to be able to report its approximate size in bytes.
Approach
The calculation is for each object is done by summing these values:
- Size of object's super class object. If object's class is directly extended from java.lang.Object class, this value is by default 8 bytes.
- Size of all primitive types and references defined in the class.
- If object has references to other non-inspectIT objects like String, Timestamps, Lists, Maps, Sets, etc., basic size of these objects.
- If object has references to Collections, size of all objects in collection.
The following table shows the overview on current inspectIT transfer objects with defined primitive types and references. It also shows the formulas that are used to calculate the basic size of non-inspectIT objects: ObjectSizesTable.ods
Realization
The interface Sizable has been introduced with only one method long getObjectSize(IObjectSizes). The DefaultData class implements this interface, but all sub-classes of mention class should override the method and provide correct calculations.
When updating the structure inspectIT transfer objects (e.g. adding new primitives or references), be sure to alter the mentioned method.
IObjectSizes interface
This interface provides the utility functions for calculating the object size of non-inspectIT objects. Implementations of this interface have to define also the size of the reference to an object. In 32-bit VM architecture reference is 4 bytes, and in 64-bit is 8 bytes. However, the 64-bit VM can run with compressed oops, that shrink the reference size.
For getting the object size the mentioned getObjectSize method has to be invoked with proper implementation of IObjectSizes that depends on VM architecture.
The class AbstractObjectSizes provides methods for calculation of generally used objects like Strings, Arrays, Lists, Maps, etc.
Testing
There are several test that assure that object calculation is as accurate as possible.
- ObjectSizesPrimitiveTypesSizeTest - test that all DefaultData objects are calling the IObjectSizes.getPrimitiveTypesSize() with correct number of references, booleans, ints,.. This will fail if a developer adds the new field to the arbitrary DefaultData class, but forgets to update the size calulcation of the class.
MemoryCalculationTest - This tests uses the Classmexer java agent to prove that our calculations are correct. The tests tries to test as much different objects and classes as possible. The Classmexer has to be started with the test with the -javaagent option. If you want to start the test from Eclipse you need to do a Ivy > Retrieve on the CMR project and add the following line to the VM arguments in the Run Configuration:
-javaagent:[PATH_TO_CMR_FOLDER]/lib/test/classmexer.jar -Xms1024m -Xmx1024m -Xmn384M