Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Size of a byte in memory - Java

I have heard mixed opinions over the amount of memory that a byte takes up in a java program.

I am aware you can store no more than +127 in a java byte, and the documentation says that a byte is only 8 bits but here I am told that it actually takes up the same amount of memory as an int, and therefore is just a Type that helps in code comprehension and not efficiency.

Can anyone clear this up, and would this be an implementation specific issue?

like image 430
Ben Page Avatar asked Oct 23 '08 14:10

Ben Page


People also ask

How much is a byte in Java?

A byte in Java is 8 bits. It is a primitive data type, meaning it comes packaged with Java. Bytes can hold values from -128 to 127.

What is the memory size of string in Java?

An empty String takes 40 bytes—enough memory to fit 20 Java characters.

What is size of int in Java?

Size of int in java. 4 bytes = 32 bit.


1 Answers

Okay, there's been a lot of discussion and not a lot of code :)

Here's a quick benchmark. It's got the normal caveats when it comes to this kind of thing - testing memory has oddities due to JITting etc, but with suitably large numbers it's useful anyway. It has two types, each with 80 members - LotsOfBytes has 80 bytes, LotsOfInts has 80 ints. We build lots of them, make sure they're not GC'd, and check memory usage:

class LotsOfBytes {     byte a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af;     byte b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf;     byte c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, cd, ce, cf;     byte d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, da, db, dc, dd, de, df;     byte e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, ea, eb, ec, ed, ee, ef; }  class LotsOfInts {     int a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af;     int b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf;     int c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, cd, ce, cf;     int d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, da, db, dc, dd, de, df;     int e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, ea, eb, ec, ed, ee, ef; }   public class Test {     private static final int SIZE = 1000000;      public static void main(String[] args) throws Exception     {                 LotsOfBytes[] first = new LotsOfBytes[SIZE];         LotsOfInts[] second = new LotsOfInts[SIZE];          System.gc();         long startMem = getMemory();          for (int i=0; i < SIZE; i++)         {             first[i] = new LotsOfBytes();         }          System.gc();         long endMem = getMemory();          System.out.println ("Size for LotsOfBytes: " + (endMem-startMem));         System.out.println ("Average size: " + ((endMem-startMem) / ((double)SIZE)));          System.gc();         startMem = getMemory();         for (int i=0; i < SIZE; i++)         {             second[i] = new LotsOfInts();         }         System.gc();         endMem = getMemory();          System.out.println ("Size for LotsOfInts: " + (endMem-startMem));         System.out.println ("Average size: " + ((endMem-startMem) / ((double)SIZE)));          // Make sure nothing gets collected         long total = 0;         for (int i=0; i < SIZE; i++)         {             total += first[i].a0 + second[i].a0;         }         System.out.println(total);     }      private static long getMemory()     {         Runtime runtime = Runtime.getRuntime();         return runtime.totalMemory() - runtime.freeMemory();     } } 

Output on my box:

Size for LotsOfBytes: 88811688 Average size: 88.811688 Size for LotsOfInts: 327076360 Average size: 327.07636 0 

So obviously there's some overhead - 8 bytes by the looks of it, although somehow only 7 for LotsOfInts (? like I said, there are oddities here) - but the point is that the byte fields appear to be packed in for LotsOfBytes such that it takes (after overhead removal) only a quarter as much memory as LotsOfInts.

like image 168
Jon Skeet Avatar answered Oct 25 '22 21:10

Jon Skeet