32
Java对象内存占 佐井@淘宝旅

Java对象内存占用

Embed Size (px)

Citation preview

Page 1: Java对象内存占用

Java对象内存占⽤用

佐井@淘宝旅⾏行

Page 2: Java对象内存占用

主要内容• 内存理解

• Java基本类型内存占⽤用

• Java对象内存占⽤用

• Java数组内存占⽤用

• Java集合内存占⽤用

Page 3: Java对象内存占用

内存

Page 4: Java对象内存占用

1 byte

— — — — — — — —8 bits 7 6 5 4 3 2 1 0

——————————

—————————2 nibbles hi low

—————————————————————1 byte byte

Page 5: Java对象内存占用

1 byte 实际值

— — — — — — — —8 bits 1 1 0 0 1 0 1 0

——————————

—————————2 nibbles C A

—————————————————————1 byte CA

Page 6: Java对象内存占用

例⼦子:Java Class 表⽰示

魔数(Magic Number)

Class版本 (Minor+Major) 常量池信息

Page 7: Java对象内存占用

⼀一个连续的byte序列, 每个byte都有⼀一个确定的地址。

Memory � (*) � 

Page 8: Java对象内存占用

Java中的数据类型

• 基本类型(non-objecs) boolean,byte,short,int,double…

• 对象new出来的都是对象

• 数组固定⼤大⼩小,最多2,147,483,648个元素

Page 9: Java对象内存占用

问题声明:本次讨论如果未特殊声明,默认为x64架构

Page 10: Java对象内存占用

装箱&基本类型?Q:Integer和int内存占⽤用⼤大⼩小⽐比例是多少?

a. 1 : 1 b. 1.33 : 1 c. 2 : 1 d. ?

Page 11: Java对象内存占用

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

a. 8b. 16 c. 28d. ?

Page 12: Java对象内存占用

更⼤大?更好?Q:HashSet与HashMap对⽐比?

a. 功能更少,占⽤用内存更少b. 功能更多,占⽤用内存更少c. ⼀一样⼀一样的d. ?

Page 13: Java对象内存占用

集合

Q:排序下列集合,假设默认构造⽅方法创建: ArrayList,HashSet,LinkedList,HashMap

Page 14: Java对象内存占用

基本类型—————————————

————type bytes—————————————

————byte 1boolean 1

char 2short 2float 4int 4

long 8double 8

—————————————————

Page 15: Java对象内存占用

了解Java Object

Page 16: Java对象内存占用

hotspot/src/share/vm/oops/oop.hpp

Page 17: Java对象内存占用

Layout of Java Object

• hashCode范围没有定义那么⼤大 !

• 64位JVM Object Header内存浪费:26/64=40%

Page 18: Java对象内存占用

关于对象指针• -XX:+UseCompressedOops

• 默认开启条件

• 是64位JVM,并且不是client VM

• Java堆的最⼤大⼤大⼩小不⼤大于⼀一个阈值

• 没有⼿手动设定过UseCompressedOops参数的值

• 没有使⽤用Garbage-First (G1) GC

Page 19: Java对象内存占用

接下来讨论默认开启UseCompressedOops

Page 20: Java对象内存占用

对象内存占⽤用java.lang.Integer 16byte

header12byte

int4 byte

java.lang.Long20byte

header12byte

int8 byte

Integer : int = 16:4 = 4:1

20byte 是否正确?

Page 21: Java对象内存占用

对象对⻬齐

对象对⻬齐:8-XX:ObjectAlignmentInBytes=32

-XX:ObjectAlignmentInBytes=4 ??

error: ObjectAlignmentInBytes=4 must be greater or equal 8

Page 22: Java对象内存占用

对象内存占⽤用java.lang.Long24byte

header12byte

int8 byte

alignment4 byte

java.lang.Boolean16byte

header12byte

boolean1 byte

alignment3 byte

空间浪费16/24=66%

空间浪费15/16=93% !!!

Page 23: Java对象内存占用

hotspot/src/share/vm/oops/arrayOop.hpp

⽐比Java对象多⼀一个“⻓长度”

数组布局

Page 24: Java对象内存占用

8-chars String

header12byte

fields12 byte

pointer4byte

alignment4 byte

chars

header16byte

header16byte

• 8个字符的字符串占64byte

• 浪费了75%空间

Page 25: Java对象内存占用

集合内存占⽤用• HashMap

!• HashSet

!• ArrayList

!• LinkedList

Page 26: Java对象内存占用

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

Page 27: Java对象内存占用

HashSet

• private transient java.util.HashMap<E,java.lang.Object> map

total=12+4+128=144byte

default:16

Page 28: Java对象内存占用

ArrayList

• private transient java.lang.Object[] elementData; • private int size;

total=(12+4+4+4)+16+4*10=80byte

default:10

Page 29: Java对象内存占用

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

Page 30: Java对象内存占用

LinkedList>ArrayList>HashMap>HashSet

Q:排序,假设默认构造⽅方法创建,并添加两个元素: ArrayList,HashSet,LinkedList,HashMap

Homework ;)

Page 31: Java对象内存占用

总结• JVM hashCode 占⽤用 32:25byte,64:31byte

• 对象对⻬齐,会浪费空间

• ⼩小字符串,空间浪费很⼤大

• 集合默认占⽤用⼤大量空间

• 64位JVM⽐比32位平均浪费20%-30%空间

• Java ⼀一切皆对象

• 尽量⽤用基本类型,不⽤用装箱类型(heap,gc)

Page 32: Java对象内存占用

QA