A colleague was recently dealing with image data which was recieved from a socket as a stream of bytes - one per pixel. These needed to be treated as unsigned and so were converted into shorts. The problem was this: the code that later scanned the images required int data. We had two choices, either hold the data a shorts and convert it to ints when needed or hold it as ints right from word go. I believed that we should hold it as ints from word go as it saved a cast later I also, wrongly I now realize, thought that and int array wouldn't take up any more space than a short array. Now I realize that a short (16 bytes) is half the size of an int (32 bytes) but I was under the impression that the VM used a whole word to store any primative type of int or smaller. Perhaps that used to be the case but it's not any more.

Any way, I banged out a bit of code to test this problem which is shown below. Note that the int array uses exactly twice the memory of the short array but allocation and population times are essentially the same.

package example;

public class MemorySize {

   
public MemorySize() {
       
for (int i = 0, n = 10; i < n; i++) {
           
System.out.println("-----------------------");
            System.out.println
("Test Number " + i);
            System.out.println
("-----------------------");
            shortTest
();
            intTest
();
            Runtime runtime = Runtime.getRuntime
();
            System.out.println
("Final Memory Usage: "
                   
+ (runtime.totalMemory() - runtime.freeMemory()));
       
}
    }

   
private void shortTest() {
       
Runtime runtime = Runtime.getRuntime();
        System.gc
();
        System.gc
();
        System.gc
();
        System.gc
();

       
// shorts
       
long start = System.currentTimeMillis();
        System.out.println
("Short Starting Memory Usage: "
               
+ (runtime.totalMemory() - runtime.freeMemory()));
       
short[] shortArray = new short[1024 * 1024 * 2];
        System.out.println
("Short Array Declared Memory Usage: "
               
+ (runtime.totalMemory() - runtime.freeMemory()));
       
for (int i = 0, n = shortArray.length; i < n; i++) {
           
shortArray[i] = 19;
       
}
       
System.out.println("Short Array Full Memory Usage: "
               
+ (runtime.totalMemory() - runtime.freeMemory()));
       
long end = System.currentTimeMillis();
        System.out.println
("Runtime for shorts: " + (end - start));

        shortArray =
null;
        System.gc
();
        System.gc
();
        System.gc
();
        System.gc
();
   
}

   
private void intTest() {
       
Runtime runtime = Runtime.getRuntime();
        System.gc
();
        System.gc
();
        System.gc
();
        System.gc
();

       
// ints
       
long start = System.currentTimeMillis();
        System.out.println
("Int Starting Memory Usage: "
               
+ (runtime.totalMemory() - runtime.freeMemory()));
       
int[] intArray = new int[1024 * 1024 * 2];
        System.out.println
("Int Array Declared Memory Usage: "
               
+ (runtime.totalMemory() - runtime.freeMemory()));
       
for (int i = 0, n = intArray.length; i < n; i++) {
           
intArray[i] = 19;
       
}
       
System.out.println("Int Array Filled Memory Usage: "
               
+ (runtime.totalMemory() - runtime.freeMemory()));
       
long end = System.currentTimeMillis();
        System.out.println
("Runtime for ints: " + (end - start));

        intArray =
null;
        System.gc
();
        System.gc
();
        System.gc
();
        System.gc
();
   
}

   
public static void main(String[] args) {
       
new MemorySize();
   
}

}