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

