jdk: java 官網上下載的,HotSpot 虛擬機java
java version "1.8.0_121" Java(TM) SE Runtime Environment (build 1.8.0_121-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
確認編譯時是 32 位仍是 64 位,對測試結果有影響。x86 爲 32 位, amd64 爲 64 位,其他我不知道git
System.out.println(System.getProperty("os.arch"));
在包名路徑下執行一下命令進行打包(注意修改相應的包名):github
jar cvfm SizeOfObject.jar manifest.mf org/seal_de/SizeOfObject.class
在運行測試程序的時候,添加 vm 參數jvm
-javaagent:{jar包路徑}\SizeOfObject.jar
public class MemoryTest { /** * -javaagent:{jar包路徑}\SizeOfObject.jar -XX:+UseCompressedOops * 使用指針壓縮,在必定狀況下64位HotSpot jvm默認指針壓縮 * *Output: *amd64 *Object: 16 * *include one int: 16 *include two int: 24 *include three int: 24 * *include one object: 16 *include one object: 24 */ static void test1() { System.out.println(System.getProperty("os.arch")); System.out.printf("%-30s%9d\n", "Object:", SizeOfObject.sizeOf(new Object())); System.out.println(); System.out.printf("%-30s%9d\n", "include one int:", SizeOfObject.sizeOf(new IntegerTestOne())); System.out.printf("%-30s%9d\n", "include two int:", SizeOfObject.sizeOf(new IntegerTestTwo())); System.out.printf("%-30s%9d\n", "include three int:", SizeOfObject.sizeOf(new IntegerTestThree())); System.out.println(); System.out.printf("%-30s%9d\n", "include one object:", SizeOfObject.sizeOf(new ReferenceTestOne())); System.out.printf("%-30s%9d\n", "include one object:", SizeOfObject.sizeOf(new ReferenceTestTwo())); } /** * -javaagent:{jar包路徑}\SizeOfObject.jar -XX:-UseCompressedOops * 不使用指針壓縮 * *Output: *amd64 *Object: 16 * *include one int: 24 *include two int: 24 *include three int: 32 * *include one object: 24 *include one object: 32 */ static void test2() { System.out.println(System.getProperty("os.arch")); System.out.printf("%-30s%9d\n", "Object:", SizeOfObject.sizeOf(new Object())); System.out.println(); System.out.printf("%-30s%9d\n", "include one int:", SizeOfObject.sizeOf(new IntegerTestOne())); System.out.printf("%-30s%9d\n", "include two int:", SizeOfObject.sizeOf(new IntegerTestTwo())); System.out.printf("%-30s%9d\n", "include three int:", SizeOfObject.sizeOf(new IntegerTestThree())); System.out.println(); System.out.printf("%-30s%9d\n", "include one object:", SizeOfObject.sizeOf(new ReferenceTestOne())); System.out.printf("%-30s%9d\n", "include one object:", SizeOfObject.sizeOf(new ReferenceTestTwo())); } public static void main(String[] args) { test2(); } static class IntegerTestOne { private int i1 = 1; } static class IntegerTestTwo { private int i1 = 1; private int i2 = 1; } static class IntegerTestThree { private int i1 = 1; private int i2 = 1; private int i3 = 1; } static class ReferenceTestOne { private Object o1 = new Object(); } static class ReferenceTestTwo { private Object o1 = new Object(); private Object o2 = new Object(); } }
64 位 | -XX:-UseCompressedOops | -XX:+UseCompressedOops |
---|---|---|
Object | 8 + 8 = 16 (對象頭+類型指針) | 8 + 4 + 4 = 16(對象頭+壓縮的類型指針+對齊填充) |
包含一個int | (8 + 8) + 4 + 4 = 24 | (8 + 4) + 4 = 16 |
包含兩個int | (8 + 8) + 4*2 = 24 | (8 + 4) + 4*2 + 4 = 24 |
包含三個int | (8 + 8) + 4*3 + 4 = 32 | (8 + 4) + 4*3 = 24 |
不壓縮引用佔 8 個字節,壓縮佔 4 個字節 | ||
包含一個引用 | (8 + 8) + 8 = 24 | (8 + 4) + 4 = 16 |
包含兩個引用 | (8 + 8) + 8*2 = 32 | (8 + 4) + 4*2 + 4 = 24 |
public class MemoryStaticTest { /** * -javaagent:{jar包路徑}\SizeOfObject.jar * 使用指針壓縮,在必定狀況下64位HotSpot jvm默認指針壓縮 * * Output: * amd64 +UseCompressedOops * StaticTest: 16 * Integer: 16 * StaticReferenceTest: 16 * * @param args */ public static void main(String[] args) { System.out.println(System.getProperty("os.arch") + " +UseCompressedOops"); System.out.printf("%-30s%9d\n", "StaticTest:", SizeOfObject.sizeOf(new StaticTest())); System.out.printf("%-30s%9d\n", "Integer:", SizeOfObject.sizeOf(new Integer(1))); System.out.printf("%-30s%9d\n", "StaticReferenceTest:", SizeOfObject.sizeOf(new StaticReferenceTest())); } static class StaticTest { private static int i1 = 1; private static int i2 = 1; private static int i3 = 1; private static int i4 = 1; private static int i5 = 1; private static int i6 = 1; } static class StaticReferenceTest { private static Object o1 = new Object(); private static Object o2 = new Object(); private static Object o3 = new Object(); private static Object o4 = new Object(); private static Object o5 = new Object(); } }
一個引用在 64 位的時候,爲何是 8 個字節;32 位的時候,爲何是 4 個字節測試
這一切均可以在 jvm 的實現中找到答案,也就是看 C++ 代碼。只是我還沒到這個階段=。=ui