Last active
August 29, 2015 14:16
-
-
Save advancedxy/2ae7c9cc7629f3aeb679 to your computer and use it in GitHub Desktop.
The simple Sizeof.java from http://www.javaworld.com/article/2077496/testing-debugging/java-tip-130--do-you-know-your-data-size-.html , all credit goes to the original auther
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env bash | |
JAVA_VERSIONS="6 7 8" | |
CompressFlag="-XX:+UseCompressedOops" | |
source_file="Sizeof.java" | |
echo "Downloading Sizeof.java" | |
curl -o $source_file https://gist.githubusercontent.com/advancedxy/2ae7c9cc7629f3aeb679/raw/197f41e7683ba74f33f858be60c856a3eae529e1/SizeofMod.java | |
for i in $JAVA_VERSIONS; do | |
JAVA_HOME=`/usr/libexec/java_home -v 1.$i` | |
echo "==Hotspot JVM 1.$i non-static filed alignment==" | |
java -version | |
for j in `echo "1 2 3"`; do | |
# in-place edit Sizeof.java | |
sed -e "s/new DummyClass[0-9]/new DummyClass$j/" -i "" $source_file | |
echo "=====DummyClass$j=====" | |
javac $source_file | |
echo "64bit JVM with UseCompressedOops on" | |
java $CompressFlag Sizeof | |
echo "64bit JVM without UseCompressedOops" | |
java `echo $CompressFlag | sed -e "s/+/-/"` Sizeof | |
done | |
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ---------------------------------------------------------------------------- | |
/** | |
* A simple class to experiment with your JVM's garbage collector | |
* and memory sizes for various data types. | |
* | |
* @author <a href="mailto:[email protected]">Vladimir Roubtsov</a> | |
*/ | |
public class Sizeof | |
{ | |
public static void main (String [] args) throws Exception | |
{ | |
// "warm up" all classes/methods that we are going to use: | |
runGC (); | |
usedMemory (); | |
// array to keep strong references to allocated objects: | |
final int count = 10000; // 10000 or so is enough for small ojects | |
Object [] objects = new Object [count]; | |
long heap1 = 0; | |
// allocate count+1 objects, discard the first one: | |
for (int i = -1; i < count; ++ i) | |
{ | |
Object object; | |
// INSTANTIATE YOUR DATA HERE AND ASSIGN IT TO 'object': | |
//object = new Object (); // 8 bytes | |
object = new Integer (i); // 16 bytes | |
//object = new Long (i); // same size as Integer? | |
//object = createString (10); // 56 bytes? fine... | |
//object = createString (9)+' '; // 72 bytes? the article explains why | |
//object = new char [10]; // 32 bytes | |
//object = new byte [32][1]; // 656 bytes?! | |
if (i >= 0) | |
objects [i] = object; | |
else | |
{ | |
object = null; // discard the "warmup" object | |
runGC (); | |
heap1 = usedMemory (); // take a "before" heap snapshot | |
} | |
} | |
runGC (); | |
long heap2 = usedMemory (); // take an "after" heap snapshot: | |
final int size = Math.round (((float)(heap2 - heap1))/count); | |
System.out.println ("'before' heap: " + heap1 + | |
", 'after' heap: " + heap2); | |
System.out.println ("heap delta: " + (heap2 - heap1) + | |
", {" + objects [0].getClass () + "} size = " + size + " bytes"); | |
} | |
// a helper method for creating Strings of desired length | |
// and avoiding getting tricked by String interning: | |
public static String createString (final int length) | |
{ | |
final char [] result = new char [length]; | |
for (int i = 0; i < length; ++ i) result [i] = (char) i; | |
return new String (result); | |
} | |
// this is our way of requesting garbage collection to be run: | |
// [how aggressive it is depends on the JVM to a large degree, but | |
// it is almost always better than a single Runtime.gc() call] | |
private static void runGC () throws Exception | |
{ | |
// for whatever reason it helps to call Runtime.gc() | |
// using several method calls: | |
for (int r = 0; r < 4; ++ r) _runGC (); | |
} | |
private static void _runGC () throws Exception | |
{ | |
long usedMem1 = usedMemory (), usedMem2 = Long.MAX_VALUE; | |
for (int i = 0; (usedMem1 < usedMem2) && (i < 1000); ++ i) | |
{ | |
s_runtime.runFinalization (); | |
s_runtime.gc (); | |
Thread.currentThread ().yield (); | |
usedMem2 = usedMem1; | |
usedMem1 = usedMemory (); | |
} | |
} | |
private static long usedMemory () | |
{ | |
return s_runtime.totalMemory () - s_runtime.freeMemory (); | |
} | |
private static final Runtime s_runtime = Runtime.getRuntime (); | |
} // end of class | |
// ---------------------------------------------------------------------------- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ---------------------------------------------------------------------------- | |
/** | |
* A simple class to experiment with your JVM's garbage collector | |
* and memory sizes for various data types. | |
* | |
* @author <a href="mailto:[email protected]">Vladimir Roubtsov</a> | |
*/ | |
public class Sizeof | |
{ | |
public static class DummyClass1 {} | |
public static class DummyClass2 extends DummyClass1 { | |
public boolean x; | |
} | |
public static class DummyClass3 extends DummyClass2 { | |
public byte y; | |
} | |
public static void main (String [] args) throws Exception | |
{ | |
// "warm up" all classes/methods that we are going to use: | |
runGC (); | |
usedMemory (); | |
// array to keep strong references to allocated objects: | |
final int count = 10000; // 10000 or so is enough for small ojects | |
Object [] objects = new Object [count]; | |
long heap1 = 0; | |
// allocate count+1 objects, discard the first one: | |
for (int i = -1; i < count; ++ i) | |
{ | |
Object object; | |
// INSTANTIATE YOUR DATA HERE AND ASSIGN IT TO 'object': | |
//object = new Object (); // 8 bytes | |
//object = new Integer (i); // 16 bytes | |
object = new DummyClass1(); | |
//object = new Long (i); // same size as Integer? | |
//object = createString (10); // 56 bytes? fine... | |
//object = createString (9)+' '; // 72 bytes? the article explains why | |
//object = new char [10]; // 32 bytes | |
//object = new byte [32][1]; // 656 bytes?! | |
if (i >= 0) | |
objects [i] = object; | |
else | |
{ | |
object = null; // discard the "warmup" object | |
runGC (); | |
heap1 = usedMemory (); // take a "before" heap snapshot | |
} | |
} | |
runGC (); | |
long heap2 = usedMemory (); // take an "after" heap snapshot: | |
final int size = Math.round (((float)(heap2 - heap1))/count); | |
System.out.println ("'before' heap: " + heap1 + | |
", 'after' heap: " + heap2); | |
System.out.println ("heap delta: " + (heap2 - heap1) + | |
", {" + objects [0].getClass () + "} size = " + size + " bytes"); | |
} | |
// a helper method for creating Strings of desired length | |
// and avoiding getting tricked by String interning: | |
public static String createString (final int length) | |
{ | |
final char [] result = new char [length]; | |
for (int i = 0; i < length; ++ i) result [i] = (char) i; | |
return new String (result); | |
} | |
// this is our way of requesting garbage collection to be run: | |
// [how aggressive it is depends on the JVM to a large degree, but | |
// it is almost always better than a single Runtime.gc() call] | |
private static void runGC () throws Exception | |
{ | |
// for whatever reason it helps to call Runtime.gc() | |
// using several method calls: | |
for (int r = 0; r < 4; ++ r) _runGC (); | |
} | |
private static void _runGC () throws Exception | |
{ | |
long usedMem1 = usedMemory (), usedMem2 = Long.MAX_VALUE; | |
for (int i = 0; (usedMem1 < usedMem2) && (i < 1000); ++ i) | |
{ | |
s_runtime.runFinalization (); | |
s_runtime.gc (); | |
Thread.currentThread ().yield (); | |
usedMem2 = usedMem1; | |
usedMem1 = usedMemory (); | |
} | |
} | |
private static long usedMemory () | |
{ | |
return s_runtime.totalMemory () - s_runtime.freeMemory (); | |
} | |
private static final Runtime s_runtime = Runtime.getRuntime (); | |
} // end of class | |
// ---------------------------------------------------------------------------- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
==Hotspot JVM 1.6 non-static filed alignment== | |
java version "1.6.0_65" | |
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-466.1-11M4716) | |
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-466.1, mixed mode) | |
=====DummyClass1===== | |
64bit JVM with UseCompressedOops on | |
'before' heap: 371568, 'after' heap: 611568 | |
heap delta: 240000, {class Sizeof$DummyClass1} size = 24 bytes | |
64bit JVM without UseCompressedOops | |
'before' heap: 524976, 'after' heap: 764976 | |
heap delta: 240000, {class Sizeof$DummyClass1} size = 24 bytes | |
=====DummyClass2===== | |
64bit JVM with UseCompressedOops on | |
'before' heap: 371568, 'after' heap: 611568 | |
heap delta: 240000, {class Sizeof$DummyClass2} size = 24 bytes | |
64bit JVM without UseCompressedOops | |
'before' heap: 524976, 'after' heap: 764976 | |
heap delta: 240000, {class Sizeof$DummyClass2} size = 24 bytes | |
=====DummyClass3===== | |
64bit JVM with UseCompressedOops on | |
'before' heap: 371568, 'after' heap: 611568 | |
heap delta: 240000, {class Sizeof$DummyClass3} size = 24 bytes | |
64bit JVM without UseCompressedOops | |
'before' heap: 524976, 'after' heap: 844976 | |
heap delta: 320000, {class Sizeof$DummyClass3} size = 32 bytes | |
==Hotspot JVM 1.7 non-static filed alignment== | |
java version "1.7.0_67" | |
Java(TM) SE Runtime Environment (build 1.7.0_67-b01) | |
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode) | |
=====DummyClass1===== | |
64bit JVM with UseCompressedOops on | |
'before' heap: 324080, 'after' heap: 484344 | |
heap delta: 160264, {class Sizeof$DummyClass1} size = 16 bytes | |
64bit JVM without UseCompressedOops | |
'before' heap: 471488, 'after' heap: 631800 | |
heap delta: 160312, {class Sizeof$DummyClass1} size = 16 bytes | |
=====DummyClass2===== | |
64bit JVM with UseCompressedOops on | |
'before' heap: 325168, 'after' heap: 485432 | |
heap delta: 160264, {class Sizeof$DummyClass2} size = 16 bytes | |
64bit JVM without UseCompressedOops | |
'before' heap: 470056, 'after' heap: 710368 | |
heap delta: 240312, {class Sizeof$DummyClass2} size = 24 bytes | |
=====DummyClass3===== | |
64bit JVM with UseCompressedOops on | |
'before' heap: 325040, 'after' heap: 565304 | |
heap delta: 240264, {class Sizeof$DummyClass3} size = 24 bytes | |
64bit JVM without UseCompressedOops | |
'before' heap: 470752, 'after' heap: 791064 | |
heap delta: 320312, {class Sizeof$DummyClass3} size = 32 bytes | |
==Hotspot JVM 1.8 non-static filed alignment== | |
java version "1.8.0_20" | |
Java(TM) SE Runtime Environment (build 1.8.0_20-b26) | |
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode) | |
=====DummyClass1===== | |
64bit JVM with UseCompressedOops on | |
'before' heap: 525816, 'after' heap: 685816 | |
heap delta: 160000, {class Sizeof$DummyClass1} size = 16 bytes | |
64bit JVM without UseCompressedOops | |
'before' heap: 704024, 'after' heap: 864024 | |
heap delta: 160000, {class Sizeof$DummyClass1} size = 16 bytes | |
=====DummyClass2===== | |
64bit JVM with UseCompressedOops on | |
'before' heap: 526088, 'after' heap: 686088 | |
heap delta: 160000, {class Sizeof$DummyClass2} size = 16 bytes | |
64bit JVM without UseCompressedOops | |
'before' heap: 704400, 'after' heap: 944400 | |
heap delta: 240000, {class Sizeof$DummyClass2} size = 24 bytes | |
=====DummyClass3===== | |
64bit JVM with UseCompressedOops on | |
'before' heap: 526360, 'after' heap: 766360 | |
heap delta: 240000, {class Sizeof$DummyClass3} size = 24 bytes | |
64bit JVM without UseCompressedOops | |
'before' heap: 704776, 'after' heap: 1024776 | |
heap delta: 320000, {class Sizeof$DummyClass3} size = 32 bytes |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
JVM 6 was downloaded from Apple. JVM 7 and 8 were downloaded from oracle.
It looks like Apple's doesn't respect to UseCompressedOoops option.
I also test a JVM 6 on one server.
This result is consisted with JVM7 and JVM8 on my local macbook.