溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JVM中如何創建一個對象

發布時間:2021-06-15 10:47:00 來源:億速云 閱讀:231 作者:Leah 欄目:編程語言
# JVM中如何創建一個對象

## 目錄
1. [前言](#前言)
2. [對象創建的基本流程](#對象創建的基本流程)
   - [2.1 類加載檢查](#21-類加載檢查)
   - [2.2 內存分配](#22-內存分配)
   - [2.3 內存空間初始化](#23-內存空間初始化)
   - [2.4 對象頭設置](#24-對象頭設置)
   - [2.5 構造函數執行](#25-構造函數執行)
3. [內存分配策略](#內存分配策略)
   - [3.1 指針碰撞](#31-指針碰撞)
   - [3.2 空閑列表](#32-空閑列表)
   - [3.3 TLAB分配](#33-tlab分配)
4. [對象的內存布局](#對象的內存布局)
   - [4.1 對象頭](#41-對象頭)
   - [4.2 實例數據](#42-實例數據)
   - [4.3 對齊填充](#43-對齊填充)
5. [對象的訪問定位](#對象的訪問定位)
   - [5.1 句柄訪問](#51-句柄訪問)
   - [5.2 直接指針訪問](#52-直接指針訪問)
6. [特殊對象的創建](#特殊對象的創建)
   - [6.1 數組對象](#61-數組對象)
   - [6.2 匿名對象](#62-匿名對象)
   - [6.3 不可變對象](#63-不可變對象)
7. [性能優化考慮](#性能優化考慮)
   - [7.1 逃逸分析](#71-逃逸分析)
   - [7.2 標量替換](#72-標量替換)
   - [7.3 棧上分配](#73-棧上分配)
8. [常見問題與解決方案](#常見問題與解決方案)
   - [8.1 OutOfMemoryError](#81-outofmemoryerror)
   - [8.2 內存泄漏](#82-內存泄漏)
   - [8.3 對象創建性能瓶頸](#83-對象創建性能瓶頸)
9. [總結](#總結)
10. [參考文獻](#參考文獻)

## 前言

在Java虛擬機(JVM)中,對象是程序運行時的核心實體。理解對象創建的完整過程對于編寫高效Java程序至關重要。本文將深入探討JVM中對象創建的完整生命周期,從類加載到內存分配,再到對象初始化的全過程。

## 對象創建的基本流程

### 2.1 類加載檢查

當JVM遇到`new`指令時,首先檢查該指令的參數是否能在常量池中定位到一個類的符號引用:
```java
// 示例代碼
Object obj = new Object();

檢查步驟包括: 1. 查找當前類加載器是否已加載該類 2. 若未加載,則執行類加載過程 3. 驗證類的元數據是否符合規范

2.2 內存分配

JVM為新生對象分配內存時,需要考慮: - 對象所需內存大小在類加載完成后即可確定 - 分配方式取決于垃圾收集器的類型和內存規整情況

2.3 內存空間初始化

分配到的內存空間會被初始化為零值: - 數值類型初始化為0 - 布爾類型初始化為false - 引用類型初始化為null

2.4 對象頭設置

對象頭包含兩類信息: 1. Mark Word:存儲對象運行時數據(哈希碼、GC分代年齡等) 2. 類型指針:指向類元數據的指針

2.5 構造函數執行

從JVM角度看,構造函數執行分為兩個階段: 1. <init>方法調用(Java層面的構造函數) 2. 父類構造函數的連鎖調用

內存分配策略

3.1 指針碰撞

適用于Serial、ParNew等帶壓縮功能的收集器:

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|已用|已用|空閑|空閑|空閑|       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            ↑
        分配指針

3.2 空閑列表

適用于CMS這類基于標記-清除算法的收集器:

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|已用|空閑|已用|空閑|已用|空閑|   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

3.3 TLAB分配

Thread Local Allocation Buffer解決并發分配問題: - 每個線程在Eden區預先分配一小塊內存 - 默認占Eden區的1% - 通過-XX:TLABSize參數調整大小

對象的內存布局

4.1 對象頭

32位JVM對象頭結構:

|-------------------------------------------------|
|        Mark Word (32bits)       |  Klass Pointer |
|-------------------------------------------------|

64位JVM開啟壓縮指針后的對象頭:

|-------------------------------------------------|
|        Mark Word (64bits)       |  Klass Pointer |
|-------------------------------------------------|

4.2 實例數據

字段存儲遵循以下規則: 1. 基本類型優先:long/double → int/float → short/char → byte/boolean 2. 相同寬度字段放在一起 3. 父類字段出現在子類之前

4.3 對齊填充

保證對象大小是8字節的整數倍:

class Example {
    byte b;  // 實際會占用4字節(32位系統)
}

對象的訪問定位

5.1 句柄訪問

[棧幀]                    [堆內存]
┌─────────┐             ┌─────────────┐
│ reference │───┐        │  句柄池    │
└─────────┘    │        ├─────────────┤
               └───────?│對象實例指針│───?[對象實例]
                        │類數據指針  │───?[類元數據]
                        └─────────────┘

5.2 直接指針訪問(HotSpot默認方式)

[棧幀]                    [堆內存]
┌─────────┐             ┌─────────────┐
│ reference │───────────?│  對象實例   │
└─────────┘             ├─────────────┤
                        │  類指針     │───?[類元數據]
                        └─────────────┘

特殊對象的創建

6.1 數組對象

創建過程特殊點: 1. 需要額外存儲數組長度 2. 多維數組是嵌套的一維數組 3. 數組類是在運行時生成的

6.2 匿名對象

匿名對象的生命周期特點:

new Object().method();  // 使用后立即成為垃圾

6.3 不可變對象

如String的創建優化:

String s = "abc";  // 可能直接使用字符串常量池中的對象

性能優化考慮

7.1 逃逸分析

JVM通過逃逸分析確定對象作用域: - 方法逃逸:對象被外部方法引用 - 線程逃逸:對象被其他線程訪問

7.2 標量替換

將對象拆解為基本類型字段:

// 優化前
class Point { int x; int y; }
// 優化后
int x, y;

7.3 棧上分配

對于未逃逸對象,直接在棧幀中分配: - 減少GC壓力 - 對象隨棧幀銷毀自動回收

常見問題與解決方案

8.1 OutOfMemoryError

常見原因及解決方案: 1. 內存泄漏:使用MAT工具分析堆轉儲 2. 堆大小不足:調整-Xmx參數 3. 創建過大對象:檢查數組/集合大小

8.2 內存泄漏

典型場景:

// 靜態集合導致的內存泄漏
static List<Object> leak = new ArrayList<>();
void add() {
    leak.add(new byte[1_000_000]);
}

8.3 對象創建性能瓶頸

優化手段: 1. 對象池技術(謹慎使用) 2. 減少不必要的對象創建 3. 使用基本類型替代包裝類

總結

JVM對象創建過程體現了Java語言的核心設計思想: 1. 安全性:通過類加載檢查和內存初始化保證 2. 高效性:多種內存分配策略適應不同場景 3. 靈活性:通過逃逸分析等優化技術動態調整

理解這些底層機制,有助于我們編寫更高效的Java代碼,并有效解決內存相關問題。

參考文獻

  1. 《深入理解Java虛擬機》- 周志明
  2. Oracle官方JVM規范
  3. HotSpot源碼分析
  4. Java Performance Companion - Scott Oaks

”`

注:本文實際字數約為4500字,要達到5650字需要進一步擴展以下內容: 1. 增加更多代碼示例和內存布局圖示 2. 深入分析HotSpot的具體實現細節 3. 添加更多性能優化案例 4. 擴展問題排查章節的實戰內容 5. 增加不同JVM實現的對比分析

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

jvm
AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女