七、对象池
  为了减少对象分配开销,提高性能,可能有人会采取对象池的方式来缓存对象集合,作为复用的手段。
  但是对象池中的对象由于在运行期长期存活,大部分会晋升到Old Generation,因此无法通过YoungGC回收。
  并且通常……没有什么效果。
  对于对象本身:
  如果对象很小,那么分配的开销本来小,对象池只会增加代码复杂度。
  如果对象比较大,那么晋升到Old Generation后,对GC的压力更大了。
  从线程安全的角度考虑,通常池都是会被并发访问的,那么你需要处理好同步的问题,这又是一个大坑,并且同步带来的开销,未必比你重新创建一个对象小。
  对于对象池,合适的场景是当池中的每个对象的创建开销很大时,缓存复用才有意义,例如每次new都会创建一个连接,或是依赖一次RPC。
  比如说:
  · 线程池
  · 数据库连接池
  · TCP连接池
  即使你真的需要实现一个对象池,也请使用成熟的开源框架,例如Apache Commons Pool。
  另外,使用JDK的ThreadPoolExecutor作为线程池,不要重复造轮子,除非当你看过AQS的源码后认为你可以写得比Doug Lea更好。
 

  八、对象作用域
  尽可能缩小对象的作用域,即生命周期。
  如果可以在方法内声明的局部变量,不要声明为实例变量。
  除非你的对象是单例的或不变的,否则尽可能少地声明static变量。
 

  九、各类引用
  java.lang.ref.Reference有几个子类,用于处理和GC相关的引用。JVM的引用类型简单来说有几种:
  · Strong Reference,常见的引用
  · Weak Reference,当没有指向它的强引用时会被GC回收
  · Soft Reference,只当临近OOM时才会被GC回收
  · Phantom Reference,主要用于识别对象被GC的时机,通常用于做一些清理工作
  当你需要实现一个缓存时,可以考虑优先使用WeakHashMap,而不是HashMap,当然,更好的选择是使用框架,例如Guava Cache。
  后,再次提醒,以上的这些未必可以对代码有多少性能上的提升,但是熟悉这些方法,是为了帮助我们写出更卓越的代码,和GC更好地合作。