Cross Section

last modified: December 20, 2005

One of the JavaIdioms.

The memory allocated for each Java object includes a header used by the JVM.

This header includes the per-object mutex, a reference to the object's class and other information used by the heap and runtime.

When allocating a large array of ValueObjects, the memory used by the headers can be a significant overhead if each object in the array is small.

An example would be:

class Point2DList  {
        static private final int POINT_COUNT = 10000;
        private Point2D[] _points;

        public Point2DList() {
                _points = new Point2D[POINT_COUNT];
                for( int i = 0; i < POINT_COUNT; i++ ) {
                        _points[i] = new Point2D.Double(0.0,0.0);
                }
        }

        public Point2D getPoint( int n ) {
                return _points[n];
        }

        public void setPoint( int n, Point2D p ) {
                _points[n] = p;
        }
}

The object header used by the HotSpot JVM is 8 bytes long and a double is stored in 8 bytes. Therefore the amount of memory allocated for each Point2D object is 24 bytes and the overhead for each object is 1/3 of its size!

Therefore: allocate multiple "cross section" arrays to hold what would be the instance variables of each logical object in the collection. Hide these arrays behind a FacadePattern that makes them appear to be a single array of objects that each have multiple instance variables.

For instance, the Point2DList example becomes:

class Point2DList {
        static private final int POINT_COUNT = 10000;
        private double[] _x; // The X "cross section"
        private double[] _y; // The Y "cross section"

        public Point2DList(){
                _x = new double[POINT_COUNT];
                _y = new double[POINT_COUNT];
                for( int i = 0; i < POINT_COUNT; i++ ) {
                        _x[i] = 0.0;
                        _y[i] = 0.0;
                }
        }

        public Point2D getPoint( int n ) {
                return new Point2D.Double( _x[n], _y[n] );
        }

        public void setPoint( int n, Point2D p ) {
                _x[n] = p.getX();
                _y[n] = p.getY();
        }
}

(This is a slightly contrived example because the x and y "cross sections" both have the double type and so could be stored in the same array, but you get the idea, I hope.)


Comments, known uses? --NatPryce

Known uses:

Alternatives:

As with all optimizations, never apply unless you've proven (with measurements, not guesses) that you need it.


Is this pattern common in Smalltalk?


CategoryPattern


Loading...