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.实例变量必须被声明为volatile3.3.3.将实例变量赋值到局部变量会带来轻微的性能提升3.4.设为null来及早清理3.4.1.eagerly deinitializing3.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 version4.3.2.不可变对象的单一表示4.3.3.通过标准化消除不可变对象的重复副本,可以极大地减少应用程序的堆使用量4.3.4.使用标准化的值通常也可以节省内存