在软件开发过程当中,Java开发者每每不用关心JVM内存的申请和回收,由于JVM会统一管理对像内存空间的申请和回收。而c/c++开发中,开发者能够自已去管理内存.这中间有管理好的,有管理很差的。好比一个新手写的基于C/C++的server上线后,可能由于内存分配问题,常常宕机,而一个基于Java的Server上线后,也会碰到反应慢,打不开,OutOfMemory等状况。 html
虽然JVM GC会统一管理对象的回收,但它也不是无所不能的,它须要你们去了解它,帮助它更好地管理咱们server端的内存。 java
系统在运行的过程当中会不断产生新的对象,这些新的对象会占用必定的内存空间。内存空间是有限的,但对象会不断的产生,因此JVM会按期去清理那些被废弃的对象(经过根搜索算法,GCRoot没法达到的对象)。这时候就会产生几个问题: c++
按期:什么时间? a.并发,一边工做,一边清理 b.暂停全部工做,清理废弃对象。 算法
从最先期的JVM垃圾回收机制来看,JVM并无采起a方式,而是采用了b方式。最先期的Serial垃圾回收器的工做方式是"Stop the World". 为何JVM没有采用a方式呢?暂不讨论。 "Stop the world"就意味着JVM须要停下手中的工做,来整理一下内存空间。这个时候Server就有了一个停顿时间,若是一个Server运行了100s,GC一次用了2s,那么它的吞吐量能够当作98%。 服务器
下面展现了GC所占时间,系统吞吐量带来的影响。 并发
是否是GC所占时间越短,系统的吞吐量越高?right! 首先感谢那些默默为提升JVM GC效率做出杰出贡献者的大神们! oracle
回忆一下,常见的垃圾回收算法: spa
废弃对象:简单来说就是没有被GCRoot直接或间接引用到的对象。 server
标记清除: 标记废弃的对象,直接清除。 会形成内存碎片。 htm
标记整理: 在标记清除算法的基础上,最后须要整理一下内存空间。消除碎片
分代复制:把空间分红几块,把有用的对象copy到另外一块,而后整块清除原来的那一块。频繁对象的复制,耗时。
只有这些是不够的,大神们又发现了部分对象在垃圾回收的过程当中,它们的命很硬,每次都是走走过场。
下图中咱们能够发现,大部分对象的生命都很短,很早就被废弃了。
最后大神们为每一个对象加上一个年龄,每经历一次GC年龄就加1.超过必定的年龄的对象群众不须要频繁的去作GC. 这个时候就发现了两个群体。一个群体是生命比较短暂,另外一个群体生命比较长。即年青代和老年代。
年青代每次GC存活的对象比较少,分代复制算法比较适合它们。由于它们须要复制不多。 老年代每次GC存活的对象比较多,比较适合标记整理算法。因此这个时候存在不一样年代的垃圾收集器。但凡事无绝对的,还须要具体状况具体分析。
同时随着硬件的提升,大部分服务器已是多CPU,这个时候就能够考虑使用基于并行的垃圾收集器。
Reference:
http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html