Java对象内存占⽤用
佐井@淘宝旅⾏行
主要内容
• 内存理解
• Java基本类型内存占⽤用
• Java对象内存占⽤用
• Java数组内存占⽤用
• Java集合内存占⽤用
内存
1 byte
— — — — — — — —
8 bits 7 6 5 4 3 2 1 0
————————
——
————————
—
2 nibbles hi low
———————————————————
——
1 byte byte
1 byte 实际值
— — — — — — — —
8 bits 1 1 0 0 1 0 1 0
————————
——
————————
—
2 nibbles C A
———————————————————
——
1 byte CA
例⼦子:Java Class 表⽰示
魔数

(Magic Number)
Class版本
(Minor+Major)
常量池信息
⼀一个连续的byte序列,
每个byte都有⼀一个确定的地址。
Memory  (*)  
Java中的数据类型
• 基本类型(non-objecs)

boolean,byte,short,int,double…
• 对象

new出来的都是对象
• 数组

固定⼤大⼩小,最多2,147,483,648个元素
问题
声明:本次讨论如果未特殊声明,默认为x64架构
装箱&基本类型?
Q:Integer和int内存占⽤用⼤大⼩小⽐比例是多少?
a. 1 : 1

b. 1.33 : 1

c. 2 : 1

d. ?





字符串?
Q:⼀一个8个字符的字符串占⽤用多少个byte?
a. 8

b. 16

c. 28

d. ?





更⼤大?更好?
Q:HashSet与HashMap对⽐比?
a. 功能更少,占⽤用内存更少

b. 功能更多,占⽤用内存更少

c. ⼀一样⼀一样的

d. ?





集合
Q:排序下列集合,假设默认构造⽅方法创建:
ArrayList,HashSet,LinkedList,HashMap
基本类型
—————————————
————type bytes
—————————————
————byte 1
boolean 1
char 2
short 2
float 4
int 4
long 8
double 8
—————————...
了解Java Object
hotspot/src/share/vm/oops/oop.hpp
Layout of Java Object
• hashCode范围没有定义那么⼤大
!
• 64位JVM Object Header内存浪费:26/64=40%
关于对象指针
• -XX:+UseCompressedOops
• 默认开启条件
• 是64位JVM,并且不是client VM
• Java堆的最⼤大⼤大⼩小不⼤大于⼀一个阈值
• 没有⼿手动设定过UseCompressedOops参数的值
...
接下来讨论默认开启UseCompressedOops
对象内存占⽤用
java.lang.Integer

16byte
header

12byte
int

4 byte
java.lang.Long

20byte
header

12byte
int

8 byte
Integer : i...
对象对⻬齐
对象对⻬齐:8
-XX:ObjectAlignmentInBytes=32	

-XX:ObjectAlignmentInBytes=4 ??	

error: ObjectAlignmentInBytes=4 must be gr...
对象内存占⽤用
java.lang.Long

24byte
header

12byte
int

8 byte
alignment

4 byte
java.lang.Boolean

16byte
header

12byte
boole...
hotspot/src/share/vm/oops/arrayOop.hpp
⽐比Java对象多⼀一个“⻓长度”
数组布局
8-chars String
header

12byte
fields

12 byte
pointer

4byte
alignment

4 byte
chars
header

16byte
header

16byte
• 8个字符的字...
集合内存占⽤用
• HashMap
!
• HashSet
!
• ArrayList
!
• LinkedList
HashMap
• transient java.util.HashMap.Entry[] table; //4+(16+4*16)
• transient int size;//4
• int threshold;//4
• final floa...
HashSet
• private transient
java.util.HashMap<E,java.lang.Object> map
total=12+4+128=144byte
default:16
ArrayList
• private transient java.lang.Object[] elementData;
• private int size;
total=(12+4+4+4)+16+4*10=80byte
default:...
LinkList
• private transient java.util.LinkedList.Entry<E> header;
• E element;
• Entry<E> next;
• Entry<E> previous;
• pr...
LinkedList>ArrayList>HashMap>HashSet
Q:排序,假设默认构造⽅方法创建,并添加两个元素:
ArrayList,HashSet,LinkedList,HashMap
Homework ;)
总结
• JVM hashCode 占⽤用 32:25byte,64:31byte
• 对象对⻬齐,会浪费空间
• ⼩小字符串,空间浪费很⼤大
• 集合默认占⽤用⼤大量空间
• 64位JVM⽐比32位平均浪费20%-30%空间
• Java ⼀...
QA
Upcoming SlideShare
Loading in …5
×

Java对象内存占用

914 views

Published on

Published in: Software
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
914
On SlideShare
0
From Embeds
0
Number of Embeds
22
Actions
Shares
0
Downloads
18
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Java对象内存占用

  1. 1. Java对象内存占⽤用 佐井@淘宝旅⾏行
  2. 2. 主要内容 • 内存理解 • Java基本类型内存占⽤用 • Java对象内存占⽤用 • Java数组内存占⽤用 • Java集合内存占⽤用
  3. 3. 内存
  4. 4. 1 byte — — — — — — — — 8 bits 7 6 5 4 3 2 1 0 ———————— —— ———————— — 2 nibbles hi low ——————————————————— —— 1 byte byte
  5. 5. 1 byte 实际值 — — — — — — — — 8 bits 1 1 0 0 1 0 1 0 ———————— —— ———————— — 2 nibbles C A ——————————————————— —— 1 byte CA
  6. 6. 例⼦子:Java Class 表⽰示 魔数
 (Magic Number) Class版本 (Minor+Major) 常量池信息
  7. 7. ⼀一个连续的byte序列, 每个byte都有⼀一个确定的地址。 Memory  (*)  
  8. 8. Java中的数据类型 • 基本类型(non-objecs)
 boolean,byte,short,int,double… • 对象
 new出来的都是对象 • 数组
 固定⼤大⼩小,最多2,147,483,648个元素
  9. 9. 问题 声明:本次讨论如果未特殊声明,默认为x64架构
  10. 10. 装箱&基本类型? Q:Integer和int内存占⽤用⼤大⼩小⽐比例是多少? a. 1 : 1
 b. 1.33 : 1
 c. 2 : 1
 d. ?
 
 

  11. 11. 字符串? Q:⼀一个8个字符的字符串占⽤用多少个byte? a. 8
 b. 16
 c. 28
 d. ?
 
 

  12. 12. 更⼤大?更好? Q:HashSet与HashMap对⽐比? a. 功能更少,占⽤用内存更少
 b. 功能更多,占⽤用内存更少
 c. ⼀一样⼀一样的
 d. ?
 
 

  13. 13. 集合 Q:排序下列集合,假设默认构造⽅方法创建: ArrayList,HashSet,LinkedList,HashMap
  14. 14. 基本类型 ————————————— ————type bytes ————————————— ————byte 1 boolean 1 char 2 short 2 float 4 int 4 long 8 double 8 ————————————— ————
  15. 15. 了解Java Object
  16. 16. hotspot/src/share/vm/oops/oop.hpp
  17. 17. Layout of Java Object • hashCode范围没有定义那么⼤大 ! • 64位JVM Object Header内存浪费:26/64=40%
  18. 18. 关于对象指针 • -XX:+UseCompressedOops • 默认开启条件 • 是64位JVM,并且不是client VM • Java堆的最⼤大⼤大⼩小不⼤大于⼀一个阈值 • 没有⼿手动设定过UseCompressedOops参数的值 • 没有使⽤用Garbage-First (G1) GC
  19. 19. 接下来讨论默认开启UseCompressedOops
  20. 20. 对象内存占⽤用 java.lang.Integer
 16byte header
 12byte int
 4 byte java.lang.Long
 20byte header
 12byte int
 8 byte Integer : int = 16:4 = 4:1 20byte 是否正确?
  21. 21. 对象对⻬齐 对象对⻬齐:8 -XX:ObjectAlignmentInBytes=32 -XX:ObjectAlignmentInBytes=4 ?? error: ObjectAlignmentInBytes=4 must be greater or equal 8
  22. 22. 对象内存占⽤用 java.lang.Long
 24byte header
 12byte int
 8 byte alignment
 4 byte java.lang.Boolean
 16byte header
 12byte boolean
 1 byte alignment
 3 byte 空间浪费16/24=66% 空间浪费15/16=93% !!!
  23. 23. hotspot/src/share/vm/oops/arrayOop.hpp ⽐比Java对象多⼀一个“⻓长度” 数组布局
  24. 24. 8-chars String header
 12byte fields
 12 byte pointer
 4byte alignment
 4 byte chars header
 16byte header
 16byte • 8个字符的字符串 占64byte • 浪费了75%空间
  25. 25. 集合内存占⽤用 • HashMap ! • HashSet ! • ArrayList ! • LinkedList
  26. 26. HashMap • transient java.util.HashMap.Entry[] table; //4+(16+4*16) • transient int size;//4 • int threshold;//4 • final float loadFactor;//4 • transient volatile int modCount;//4 • private transient java.util.Set<java.util.Map.Entry<K,V>> entrySet;//4 • transient volatile java.util.Set<K> keySet;//4 • transient volatile java.util.Collection<V> values;//4 total=12+4*8+16+4*16=128byte default:16
  27. 27. HashSet • private transient java.util.HashMap<E,java.lang.Object> map total=12+4+128=144byte default:16
  28. 28. ArrayList • private transient java.lang.Object[] elementData; • private int size; total=(12+4+4+4)+16+4*10=80byte default:10
  29. 29. LinkList • private transient java.util.LinkedList.Entry<E> header; • E element; • Entry<E> next; • Entry<E> previous; • private transient int size; default:0 total=(12+4+4+4)+12+4*3=48byte
  30. 30. LinkedList>ArrayList>HashMap>HashSet Q:排序,假设默认构造⽅方法创建,并添加两个元素: ArrayList,HashSet,LinkedList,HashMap Homework ;)
  31. 31. 总结 • JVM hashCode 占⽤用 32:25byte,64:31byte • 对象对⻬齐,会浪费空间 • ⼩小字符串,空间浪费很⼤大 • 集合默认占⽤用⼤大量空间 • 64位JVM⽐比32位平均浪费20%-30%空间 • Java ⼀一切皆对象 • 尽量⽤用基本类型,不⽤用装箱类型(heap,gc)
  32. 32. QA

×