技术开发 频道

如何驯服java GC导致暂停?使用16GiB

  配置恰当的缓存Cache策略来解决GC问题也相当重要,我们提倡基于内存的领域对象编程,大量数据都在缓存中in-memory,如何保证他们的生命周期和JVM的垃圾回收机制不冲突,也是一种实际问题,文章提出下面几点:

  1.为缓存增加失效期,让新生代的GC期间要长于缓存的失效期,也就是缓存中对象数据失效后,正好GC启动后可以回收这些失效对象。

  2.增加延长新生代的GC期间。

  3.在缓存中使用弱引用。缓存产品自己的事,和我们应用者无关。

  4.增加缓存大小,我个人经验尽可能将数据库数据以领域对象方式都加载到内存中。

  JVM首先分配所有对在新生代,然后将幸存对象(一般是缓存中对象)再分配到旧生代,或再分配到新生代,这些对象的拷贝将耗费时间导致新生代收集暂停,两种选择:

  1.在第一次收集时,就将对象复制到旧生代

  2.第二次收集时,将对象复制到旧生代。

  第一种办法将导致一些短生命周期对象复制到旧生代,第二种办法需要注意新生代垃圾收集的频度和长生命周期对象是否小。

  对于一个巨大的heap,新生代垃圾收集暂停主要是在空间扫描和复制幸存对象上,在新生代大小上需要取得一个平衡,旧生代大小足够放入应用的数据,比如JiveJdon一天下来缓存的大小是200K左右(每天启动的情况下),只要旧生代大小大于这个值即可,不能太大,也不能太小。

  增加新生代大小要增加整个JVM大小,否则就会降低旧生代的内存大小。

  可以配置CMS短期暂停:–XX:CMSWaitDuration –设置收集暂停的最大间隔时间,越大你的应用将被暂停,类似死机没有反应。XX:+CMSScavengeBeforeRemark 可以避免在收集期间同时扫描。

0
相关文章