java如何實現(xiàn)打印list對象占用多大內(nèi)存
在 Java 中精確計算 List 對象占用的內(nèi)存大小需要考慮對象頭、引用、數(shù)組開銷和元素對象本身的大小。以下是幾種實現(xiàn)方式:
方法 1:使用 Java Object Layout (JOL) 工具(推薦)
JOL 是 OpenJDK 提供的官方工具,可精確分析對象內(nèi)存布局。
步驟:
添加 Maven 依賴:
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.17</version> <!-- 檢查最新版本 -->
</dependency>
打印內(nèi)存占用:
import org.openjdk.jol.info.ClassLayout;
import org.openjdk.jol.info.GraphLayout;
import java.util.ArrayList;
import java.util.List;
public class ListMemorySize {
public static void main(String[] args) {
// 創(chuàng)建并填充 List
List<String> list = new ArrayList<>();
for (int i = 0; i < 100; i++) {
list.add("Hello" + i); // 添加100個字符串
}
// 1. 打印 List 對象本身的大?。ú话ㄔ兀?
System.out.println("List 對象本身大小:");
System.out.println(ClassLayout.parseInstance(list).toPrintable());
// 2. 打印整個 List 結(jié)構(gòu)的總大小(包括元素)
long totalSize = GraphLayout.parseInstance(list).totalSize();
System.out.println("List + 所有元素總內(nèi)存: " + totalSize + " bytes");
}
}
輸出示例:
List 對象本身大小:
ArrayList instance internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0)
8 4 (object header: class) 0x000012c0
12 4 int AbstractList.modCount 100
16 4 int ArrayList.size 100
20 4 Object[] ArrayList.elementData (object)
Instance size: 24 bytes
List + 所有元素總內(nèi)存: 4160 bytes
方法 2:手動估算(僅參考)
對于 ArrayList:
1.ArrayList 對象本身:
- 對象頭:12 bytes(64位 JVM 開啟壓縮指針時)
int modCount和int size:各 4 bytesObject[] elementData引用:4 bytes- 總計 ≈ 24 bytes
2.底層數(shù)組 Object[]:
- 數(shù)組對象頭:16 bytes
- 數(shù)組長度:4 bytes
- 每個引用:4 bytes × 數(shù)組容量(如默認容量 10)
- 總計 = 16 + 4 + (4 × capacity)
3.元素對象:
每個元素對象的實際大?。ㄈ?String 對象約 24-48 bytes)
方法 3:使用Instrumentation(需 Java Agent)
適用于需要精確計算的場景,但配置較復(fù)雜。
創(chuàng)建 Agent 類:
import java.lang.instrument.Instrumentation;
public class MemoryAgent {
private static Instrumentation instrumentation;
public static void premain(String args, Instrumentation inst) {
instrumentation = inst;
}
public static long getObjectSize(Object o) {
return instrumentation.getObjectSize(o);
}
}
在 MANIFEST.MF 中聲明:
Premain-Class: MemoryAgent
計算大小:
public class Main {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
// 添加元素...
// 僅計算 List 本身(不包括元素)
long size = MemoryAgent.getObjectSize(list);
System.out.println("List size: " + size + " bytes");
}
}
關(guān)鍵注意事項
1.JVM 差異:
- 對象頭大?。ㄍǔ?8-16 bytes)
- 是否開啟壓縮指針(
-XX:+UseCompressedOops) - 內(nèi)存對齊(通常按 8 bytes 對齊)
2.包含元素:
ClassLayout只分析對象本身GraphLayout會遞歸計算所有引用對象
3.常見 List 實現(xiàn):
ArrayList:底層是數(shù)組,預(yù)分配空間可能大于實際元素數(shù)LinkedList:每個元素含前后指針,開銷更大
總結(jié)建議
- 快速查看內(nèi)存:使用 JOL(
GraphLayout.parseInstance(list).totalSize()) - 生產(chǎn)環(huán)境監(jiān)控:使用 JVM 工具(如 VisualVM、JProfiler)
- 精確測量:結(jié)合
Instrumentation和 JOL
重要:Java 中對象內(nèi)存占用是近似值,不同 JVM 實現(xiàn)和垃圾回收器會導(dǎo)致結(jié)果差異。
到此這篇關(guān)于java如何實現(xiàn)打印list對象占用多大內(nèi)存的文章就介紹到這了,更多相關(guān)java打印list對象占用內(nèi)存內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java內(nèi)部類持有外部類導(dǎo)致內(nèi)存泄露的原因與解決方案詳解
這篇文章主要為大家詳細介紹了Java因為內(nèi)部類持有外部類導(dǎo)致內(nèi)存泄露的原因以及其解決方案,文中的示例代碼講解詳細,希望對大家有所幫助2022-11-11
SpringBoot?整合?ShardingSphere4.1.1實現(xiàn)分庫分表功能
ShardingSphere是一套開源的分布式數(shù)據(jù)庫中間件解決方案組成的生態(tài)圈,它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar(計劃中)這3款相互獨立的產(chǎn)品組成,本文給大家介紹SpringBoot?整合?ShardingSphere4.1.1實現(xiàn)分庫分表,感興趣的朋友一起看看吧2023-12-12
在IDEA中如何設(shè)置最多顯示文件標簽個數(shù)
在使用IDEA進行編程時,可能會同時打開多個文件,當文件過多時,文件標簽會占據(jù)大部分的IDEA界面,影響我們的編程效率,因此,我們可以通過設(shè)置IDEA的文件標簽顯示個數(shù),來優(yōu)化我們的編程環(huán)境,具體的設(shè)置方法如下2024-10-10
Spring Boot利用@Async異步調(diào)用:ThreadPoolTaskScheduler線程池的優(yōu)雅關(guān)閉詳解
這篇文章主要給大家介紹了關(guān)于Spring Boot利用@Async異步調(diào)用:ThreadPoolTaskScheduler線程池的優(yōu)雅關(guān)閉的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-05-05
Java Chassis3注冊中心分區(qū)隔離技術(shù)解密
這篇文章主要為大家介紹了Java Chassis3注冊中心分區(qū)隔離技術(shù)解密,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2024-01-01
詳解Spring boot使用Redis集群替換mybatis二級緩存
本篇文章主要介紹了詳解Spring boot使用Redis集群替換mybatis二級緩存,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-05-05

