引言:
申明:本文翻译自Sangmin Lee的Understanding Java Garbage Collection.
原文链接:http://www.cubrid.org/blog/dev-platform/understanding-java-garbage-collection/
知道Java中GC的工作原理有啥好处呢?首先,是软件工程师好奇心得到满足;其次,让你写出更加优秀的Java应用。这其实是一个我个人的且主观的想法,但我认为作为一个优秀的Java开发者, 熟练和精通GC是必须的。如果你知道GC的工作细节,那就意味着你可以掌控应用程序的规模。如果你认真的考虑过如何选择GC算法,那么你对自己开发的程序的 特性是完全可以掌控的。当然,这并不是评判一个好的开发者的准则。但是,所 有人都认为GC是优秀的Java开发者的必备技能。
本文是“成为Java GC专家”系列的第一篇。本文将会简要的阐述GC,后续,我 会分析GC的状态和GC调优的例子。
本文将采用通熟易懂的方式来介绍下GC。我希望这篇文章真的能够帮助大家。 事实上,我的同事已经在JAVA内刊上发表了很多的类似的文章,这些文章在Twitter 上非常受欢迎,你也可以去看看。
正文:
言归正传,在了解GC前,有些术语我们应该知道。“stop-the-world”,无论 你看哪种GC算法,这个词都将出现。它意味着JVM停止当前应用程序的运行,转而 去执行GC。当“stop-the-world”时,除了执行GC的线程外,其他线程都将中断运行。 只有GC工作完成后,这些中断的线程才会恢复执行。所谓的GC调优意味着我们要降 低GC执行的频率,即“stop-the-world”的执行次数。
GC中的“代”概念
Java并未在代码中显示地分配和释放内存。一些人认为将对象设置为NULL或者 调用System.gc() 方法来显示释放内存。将对象设置NULL是很容易的,但调用System.gc() 很大程度上回影响系统的性能,所以是不被建议的。(幸运的是,至今为止,我还未 看见有开发者这样干过。)
在Java中,开发者是没有必要在代码中显示释放内存的。GC会找出那些没有用的 对象并且回收内存。GC的创建是基于以下两种预设。(说是推理可能更加准确点。)
1)大部分对象生命周期短,转瞬即逝;
2)旧生代(old Generation)对于新生代(young Generation)的引用数量可控。
上述的两种预设就是所谓的“weak generational hypothesis”。所以,为了更加 有说服力,HotSpot VM将内存在物理上划分为young generation:和 old generation
young generation:大部分新建的对象都位于这里。因为大部分对象很快就没有用 了,所以大部分对象在young generation创建,然后销毁。当这里一个对象销毁时,我们称之为
minor GC。
Old generation: 那些没有被销毁并且在young generation存活下来的对象被拷贝 到这里。Old
generation占用的空间比young generation大许多。正式由于这个缘故, GC在这里操作的次数比在young generation少。当这里一个对象销毁时,我们称之为 major GC或者full GC。
看图说话:
Figure 1: GC Area & Data Flow.
上面图中的permanent generation也叫作method area(方法区),这里存放类或者内置字符集。
注意,这里可不是为old generation一直存活的对象准备的。GC也会回收这里的,且发生在major GC.
一些人可能会有疑问:
如果 old generation的对象引用到 young generation的对象咋办?
为了处理这种情况,在old generation中有一种叫做“card table”的东东被设计处来,大小为512 byte。 当上述情况发生时,就被记录到这个“card table”中。当GC在young generation执行时,会扫描这张表,而不会 去检查old
generation所有对象的引用,以此来决定是否回收。这张表被一个叫做“write barrie”的东东管理。 这个 “write barrie”可以保证"minor GC"的高性能。可能一高额的消耗会因此产
生,但总体上GC的执行时长变短了。
上图:
Figure 2: Card Table Structure.
好了,今晚先译到这里,水平有限,不足之处还望大家指正。
2016-05-08 01:49