读Java性能权威指南(第2版)笔记12_堆内存中
Posted lying7
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了读Java性能权威指南(第2版)笔记12_堆内存中相关的知识,希望对你有一定的参考价值。
1. 减少内存使用
1.1. 减少堆内存的使用
1.1.1. 使用更少的内存意味着堆被填满的频率会降低,需要的GC周期会更少,其效果也可以成倍增强
1.1.2. 更少的新生代回收意味着对象的晋升年龄增加的频率降低
1.1.3. 对象晋升到老年代的可能性也降低了
1.1.4. Full GC周期(或者并发GC周期)的数量将减少
1.2. 方法
1.2.1. 减小对象大小
1.2.2. 使用对象的延迟初始化
1.2.3. 使用标准化对象
2. 减小对象大小
2.1. 可以提高GC的效率
2.2. 即使实例变量是null,也会消耗对象类内的空间
2.3. 让对象更小
2.3.1. 不太可能将堆的大小增加10%
2.3.2. 将堆中一半对象的大小减小20%可以达到相同的目标
2.3.2.1. Java 11对String对象进行了这样的优化
2.3.2.2. Java 11的用户可以将堆的最大大小设置得比Java 8要求的小25%,而不会对GC或性能产生影响
2.4. 对象对齐和对象大小
2.4.1. 对象的大小总是被填充到8字节的倍数
2.4.2. 在对象中消除一些实例字段或减小一些字段的大小,可能会产生收益,也可能不会,但我们没有理由不这么做
2.4.3. jol工具
2.4.3.1. 可以计算对象的大小
2.5. 时间与空间的权衡
2.5.1. 对象字段存储的是基于一些数据计算出的结果
2.5.1.1. 使用内存(空间)存储这个值
2.5.1.2. 花费时间(CPU周期)在需要的时候计算这个值
2.5.1.2.1. 如果减少GC是目标,大多数人可能更倾向于重新计算
2.5.2. 适用于CPU时间
2.5.2.1. 使用额外的内存会导致GC消耗更多的CPU周期
3. 使用延迟初始化
3.1. 只有在常用路径不会初始化变量时,才应该使用延迟初始化
3.1.1. 最好只在相关操作使用得不那么频繁时使用
3.1.2. 操作很常用,那就不能节省内存了
3.1.2.1. 因为内存总是会被分配
3.2. 对于使用线程安全对象的代码,延迟初始化时应该使用双重检查锁
3.3. 同步瓶颈
3.3.1. 通过惯用的双重检查锁来解决
3.3.2. 实例变量必须被声明为volatile
3.3.3. 将实例变量赋值到局部变量会带来轻微的性能提升
3.4. 设为null来及早清理
3.4.1. eagerly deinitializing
3.4.2. 在有限的情况下有用
3.4.3. 显式地将一个对象引用设置为null基本不会给性能带来什么好处
3.4.4. 如果一个长期存活的类会缓存并丢弃对象引用,则必须注意避免过时引用
4. 使用不可变对象和标准化对象
4.1. 不可变对象为标准化这种特殊的生命周期管理提供了可能性
4.2. 最常见的Java对象是不可变的String对象
4.2.1. 字符串可以调用intern()方法来找到这个字符串的标准化版本
4.3. 对象的标准化版本
4.3.1. canonical version
4.3.2. 不可变对象的单一表示
4.3.3. 通过标准化消除不可变对象的重复副本,可以极大地减少应用程序的堆使用量
4.3.4. 使用标准化的值通常也可以节省内存
以上是关于读Java性能权威指南(第2版)笔记12_堆内存中的主要内容,如果未能解决你的问题,请参考以下文章