Java のオブジェクトのメモリ使用量について2

http://www.javaworld.com/javaworld/javaqa/2003-12/02-qa-1226-sizeof.html

こっちの記事には ObjectProfiler のことがかいてあった。
オブジェクトの sizeof を取るには・・・という趣旨。

2003 年の記事なんだな、、、ふるい・・・。
(でも、JDK1.6 でも動く)

実際動かしてみるとなかなか良く動く。

    private static class A {
	public String a;
	public HashMap b;
	private String c = "aaa";
	private Date d = new Date();
	private Calendar e = Calendar.getInstance();
    }

...

	A obj = new A();
	obj.a = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
	obj.b = new HashMap();
	obj.b.put(11234, 234);
	obj.b.put("hogahoge", 23432);
	obj.b.put("hogehoge", 23432);
	obj.b.put("hogehoge", 23432);
	obj.b.put("hogehoge", 23432);

というオブジェクトを、ObjectProfile すると、
以下のような結果が返る。

この例だと、1247 byte であることがわかる。

obj size = 1247 bytes
  1247 -> <INPUT> : Main$A
    663 (53.2%) -> Main$A#e : GregorianCalendar
      230 (18.4%) -> Calendar#zone : sun.util.calendar.ZoneInfo, refcount=2
        96 (7.7%) -> sun.util.calendar.ZoneInfo#transitions : long[]
          96 (7.7%) -> <shell: long[], length=10>
        60 (4.8%) -> TimeZone#ID : String
          36 (2.9%) -> String#value : char[]
            36 (2.9%) -> <shell: char[], length=10>
          24 (1.9%) -> <shell: 3 prim/1 ref fields>
        46 (3.7%) -> <shell: 6 prim/5 ref fields>
        28 (2.2%) -> sun.util.calendar.ZoneInfo#offsets : int[]
          28 (2.2%) -> <shell: int[], length=3>
      105 (8.4%) -> <shell: 15 prim/9 ref fields>
      91 (7.3%) -> GregorianCalendar#gdate : sun.util.calendar.Gregorian$Date, refcount=2
        91 (7.3%) -> <shell: 17 prim/3 ref fields>
      84 (6.7%) -> Calendar#fields : int[]
        84 (6.7%) -> <shell: int[], length=17>
      84 (6.7%) -> Calendar#stamp : int[]
        84 (6.7%) -> <shell: int[], length=17>
      33 (2.6%) -> Calendar#isSet : boolean[]
        33 (2.6%) -> <shell: boolean[], length=17>
      24 (1.9%) -> GregorianCalendar#zoneOffsets : int[]
        24 (1.9%) -> <shell: int[], length=2>
      12 (1%) -> GregorianCalendar#calsys : sun.util.calendar.Gregorian
        12 (1%) -> <shell: 0 prim/1 ref fields>
    352 (28.2%) -> Main$A#b : HashMap
      312 (25%) -> HashMap#table : HashMap$Entry[]
        92 (7.4%) -> HashMap#table[10] : HashMap$Entry
          56 (4.5%) -> HashMap$Entry#key : String
            32 (2.6%) -> String#value : char[]
              32 (2.6%) -> <shell: char[], length=8>
            24 (1.9%) -> <shell: 3 prim/1 ref fields>
          24 (1.9%) -> <shell: 1 prim/3 ref fields>
          12 (1%) -> HashMap$Entry#value : Integer
            12 (1%) -> <shell: 1 prim/0 ref fields>
        92 (7.4%) -> HashMap#table[12] : HashMap$Entry
          56 (4.5%) -> HashMap$Entry#key : String
            32 (2.6%) -> String#value : char[]
              32 (2.6%) -> <shell: char[], length=8>
            24 (1.9%) -> <shell: 3 prim/1 ref fields>
          24 (1.9%) -> <shell: 1 prim/3 ref fields>
          12 (1%) -> HashMap$Entry#value : Integer
            12 (1%) -> <shell: 1 prim/0 ref fields>
        80 (6.4%) -> <shell: HashMap$Entry[], length=16>
        48 (3.8%) -> HashMap#table[9] : HashMap$Entry
          24 (1.9%) -> <shell: 1 prim/3 ref fields>
          12 (1%) -> HashMap$Entry#key : Integer
            12 (1%) -> <shell: 1 prim/0 ref fields>
          12 (1%) -> HashMap$Entry#value : Integer
            12 (1%) -> <shell: 1 prim/0 ref fields>
      40 (3.2%) -> <shell: 4 prim/4 ref fields>
    138 (11.1%) -> Main$A#a : String
      114 (9.1%) -> String#value : char[]
        114 (9.1%) -> <shell: char[], length=49>
      24 (1.9%) -> <shell: 3 prim/1 ref fields>
    46 (3.7%) -> Main$A#c : String
      24 (1.9%) -> <shell: 3 prim/1 ref fields>
      22 (1.8%) -> String#value : char[]
        22 (1.8%) -> <shell: char[], length=3>
    28 (2.2%) -> <shell: 0 prim/5 ref fields>
    20 (1.6%) -> Main$A#d : Date
      20 (1.6%) -> <shell: 1 prim/1 ref fields>


size fraction filter with threshold=0.25:
  1247 -> <INPUT> : Main$A
    663 (53.2%) -> Main$A#e : GregorianCalendar
    352 (28.2%) -> Main$A#b : HashMap
      312 (25%) -> HashMap#table : HashMap$Entry[]


ただし、先の記事で書いた、8byte 単位のバウンダリとかについては
考慮されてないし、その他の原因でもずれることはある。
記事の後半部にその辺の記載が。