看到李建斌《JVM
内存管理
/GC
模型
/
编写
GC
友好的代码》的ppt,将其中的实例部分摘录下来。
另外JavaOne2007上有篇《Garbage-Collection-Friendly Programming》的68页PPT,介绍得挺不错,下载地址 http://img.pusuo.net/2009-08-13/110313148.pdf
• JVM 喜欢生命周期短的,小的对象
另外JavaOne2007上有篇《Garbage-Collection-Friendly Programming》的68页PPT,介绍得挺不错,下载地址 http://img.pusuo.net/2009-08-13/110313148.pdf
• JVM 喜欢生命周期短的,小的对象
•
JVM
创建对象的速度非常高,已经非常接近
C++
•
GC
回收生命周期短的对象非常高效
–
前面提到的新生代复制算法,对于生命周期短的对象,不需要扫描和复制就能回收
–
对象定义在错误的范围 (WrongScope)
•
使用更多生命周期短的、小的、不改变指向
(immutable)
的对象
•
不要害怕创建临时对象作为中间计算的结果
•
不要滥用对象池
(Object Pool)
–
出于节俭的心态,程序员总是倾向于使用对象池作为缓冲
•
除非创建对象的开销较大
,
否则对象池不一定能提高性能,反而会影响
GC
效率
–
比如从数据库
query
生成对象,
pooling
是有帮助的;但如果不涉及到
DB/IO/Network/
紧张资源的对象创建,
pooling
反而有反效果
–
对象池生命周期长,每次
full
gc
都要处理
(mark, compact,
etc
)
–
如果涉及多线程共享问题,对象池还可能带来同步等额外开销,得不偿失
–
容易产生内存泄漏
•
当使用
Array-based
的数据结构
(
ArrayList
,
HashMap
等
)
时,尽量减少
resize
–
比如
new
ArrayList
时,尽量估算
size
,在创建的时候把
size
确定
–
减少
resize
可以避免没有必要的
array copying,
gc
碎片等问题
•
如果一个
List
只需要顺序访问,不需要随机访问(
Random Access
),用
LinkedList
代替
ArrayList
–
LinkedList
本质是链表,不需要
resize
, 但只适用于顺序访问
•
避免
Java
内存泄漏
•
Java
内存泄漏
VS C/C++
内存泄漏
–
C/C++
内存泄漏:把东西锁到抽屉里面,但钥匙丢了
(Object unreachable)
–
Java
内存泄漏:把有用和没用的东西都摆满房间,清洁工(
GC
)分不清哪些是有用的,哪些是没用的。没用的东西没办法清理。
(Object reachable but unused)
•
Java
内存泄漏类型
–
传统型:
Heap
越来越大,直到
OOM
–
临时型:
Heap
临时变得很大,在某个时刻会突然变很小。导致频繁
Full GC
•
Java
内存泄漏的经典原因
–
对象定义在错误的范围
(Wrong Scope)
–
异常
(Exception)
处理不当
–
集合数据管理不当
–
String
陷阱
对象定义在错误的范围 (WrongScope)
•
JVM
喜欢生命周期短的对象,这样做已经足够高效