### 對象的指向
先來看一段代碼:
~~~
package?com.zwx.jvm;
public?class?HeapMemory?{
????private?Object?obj1?=?new?Object();
????public?static?void?main(String[]?args)?{
????????Object?obj2?=?new?Object();
????}
}
~~~
上面的代碼中,obj1 和obj2在內存中有什么區別?
我們先來回憶一下JVM系列1的文章中有提到,方法區存儲每個類的結構,比如:運行時常量池、屬性和方法數據,以及方法和構造函數等數據。所以我們這個obj1是存在方法區的,而new會創建一個對象實例,對象實例是存儲在堆內的,于是就有了下面這幅圖(**方法區指向堆**):

而obj2 是屬于方法內的局部變量,存儲在Java虛擬機棧內的棧幀中的局部變量表內,這就是經典的**棧指向堆**:

這里我們再來思考一下,我們一個變量指向了堆,而堆內只是存儲了一個實例對象,那么堆內的示例對象是如何知道自己屬于哪個Class,也就是說這個實例是如何知道自己所對應的類元信息的呢?這就涉及到了一個Java對象在內存中是如何布局的
### Java內存模型
對象內存中可以分為三塊區域:對象頭(Header),實例數據(Instance Data)和對齊填充(Padding),**以64位操作系統為例(未開啟指針壓縮的情況)**Java對象布局如下圖所示:

其中對象頭中的Mark Word中的詳細信息在文章synchronized鎖升級原理中有詳細介紹。上圖中的對齊填充不是一定有的,如果對象頭和實例數據加起來剛好是8字節的倍數,那么就不需要對齊填充
### [Object obj=new Object()占用字節]
這是網上很多人都會提到的一個問題,那么結合上面的Java內存布局,我們來分析下,以64位操作系統為例,new Object()占用大小分為兩種情況:
* 未開啟指針壓縮 ? ? 占用大小為:**8(Mark Word)+8(Class Pointer)=16字節**
* 開啟了指針壓縮(默認是開啟的) ? ? 開啟指針壓縮后,Class Pointer會被壓縮為4字節,最終大小為:**8(Mark Word)+4(Class Pointer)+4(對齊填充)=16字節**
結果到底是不是這個呢?我們來驗證一下。首先引入一個pom依賴:
~~~
<dependency>????
<groupId>org.openjdk.jol</groupId>????
<artifactId>jol-core</artifactId>????
<version>0.10</version>
</dependency>
~~~
```
package?com.zwx.jvm;
import?org.openjdk.jol.info.ClassLayout;
publicclass?HeapMemory?{
public?static?void?main(String\[\]?args)?{
????????Object?obj?=?new?Object();
????????System.out.println(ClassLayout.parseInstance(obj).toPrintable());
????}
}
```
輸出結果如下:

最后的結果是16字節,沒有問題,這是因為默認開啟了指針壓縮,那我們現在把指針壓縮關閉之后再去試試

再次運行,得到如下結果:

可以看到,這時候已經沒有了對齊填充部分了,但是占用大小還是16位。
下面我們再來演示一下如果一個對象中帶有屬性之后的大小。
新建一個類,內部只有一個byte屬性:

開啟指針壓縮,占用16字節:

關閉指針壓縮,占用24字節:

這個時候就能看出來開啟了指針壓縮的優勢了,如果不斷創建大量對象,指針壓縮對性能還是有一定優化的
- java演變
- JDK各個版本的新特性
- JDK1.5新特性
- JDK1.6新特性
- JDK1.7新特性
- JDK1.8新特性
- JAVA基礎
- 面向對象特性
- 多態
- 方法重載
- 方法重寫
- class
- 常量
- 訪問修飾符
- 類加載路徑
- java-equals
- 局部類
- java-hashCode
- Java類初始化順序
- java-clone方法
- JAVA對象實例化的方法
- 基礎部分
- JAVA基礎特性
- JAVA關鍵字
- javabean
- static
- 日期相關
- final
- interface
- 函數式接口
- JAVA異常
- 異常屏蔽
- try-with-resource資源泄露
- JAVA引用
- WeakReference
- SoftReference
- PhantomReference
- 位運算符
- try-with-resource語法糖
- JDK冷知識
- JAVA包裝類
- JAVA基本類型與包裝類
- java.lang.Boolean
- java.lang.Integer
- java.lang.Byte
- java.lang.Short
- java.lang.Long
- java.lang.Float
- java.lang.Double
- java.lang.Character
- 日期相關
- TemporalAdjusters
- String
- 字符串常量池
- String拼接
- String編譯期優化
- StringBuilder&StringBuffer
- intern
- 注解
- java標準注解
- 內置注解
- 元注解
- 自定義注解
- 注解處理器
- JVM注解
- Java8 Annotation新特性
- 反射-Reflective
- Reflection
- Class
- Constructor
- Method
- javabean-property
- MethodHandles
- 泛型
- 類型擦除
- bridge-method
- Accessor&Mutator方法
- enum
- JAVA數組
- finalize方法
- JAR文件
- JAVA高級編程
- CORBA
- JMX
- SPI
- Java SPI使用約定
- ServiceLoader
- 實際應用
- IO
- 工具類
- JDK常用工具類
- Objects
- System
- Optional
- Throwable
- Collections
- Array
- Arrays
- System
- Unsafe
- Number
- ClassLoader
- Runtime
- Object
- Comparator
- VarHandle
- 數據結構
- 棧-Stack
- 隊列(Queue)
- Deque
- PriorityQueue
- BlockingQueue
- SynchronousQueue
- ArrayBlockingQueue
- LinkedBlockingQueue
- PriorityBlockingQueue
- ConcurrentLinkedQueue
- 列表
- 迭代器
- KV鍵值對數據類型
- HashMap
- TreeMap
- Hash沖突
- ConcurrentHashMap
- JDK1.7 ConcurrentHashMap結構
- jdk7&jdk8區別
- 集合
- Vector
- Stack
- HashSet
- TreeSet
- ArrayList
- LinkedList
- ArrayList && LinkedList相互轉換
- 線程安全的集合類
- 集合類遍歷性能
- 并發容器
- CopyOnWriteArrayList
- ConcurrentHashMap
- 同步容器
- BitMap
- BloomFilter
- SkipList
- 設計模式
- 設計模式六大原則
- 單例模式
- 代理模式
- 靜態代理
- 動態代理
- JDK動態代理
- cglib動態代理
- spring aop
- 策略模式
- SpringAOP策略模式的運用
- 生產者消費者模式
- 迭代器模式
- 函數式編程
- 方法引用
- 性能問題
- Lambda
- Lambda類型檢查
- Stream
- findFirst和findAny
- reduce
- 原始類型流特化
- 無限流
- 收集器
- 并行流
- AOP
- 靜態織入
- aspect
- aspect的定義
- AspectJ與SpringAOP
- 動態織入
- 靜態代理
- 動態代理
- JDK動態代理
- CGLib動態代理
- Spring AOP
- SpringAOP五種通知類型
- @Before
- @AfterReturning
- @AfterThrowing
- @After
- @Around
- Aspect優先級
- SpringAOP切點表達式
- within
- execution
- 嵌套調用
- 系統優化與重構
- 重疊構造器模式
- 工具類構造器優化
- 常見面試題
- new Object()到底占用幾個字節
- 訪問修飾符
- cloneable接口實現原理
- 異常分類以及處理機制
- wait和sleep的區別
- 數組在內存中如何分配
- 類加載為什么要使用雙親委派模式,有沒有什么場景是打破了這個模式
- 類的實例化順序
- 附錄
- JAVA術語
- FAQ
- 墨菲定律
- 康威定律
- 軟件設計原則
- 阿姆達爾定律
- 字節碼工具
- OSGI