就像人的生老病死一样,变量也有自己独特的生命历程。当变量被声明的那一刻起,变量就算是诞生了。
1. 何时消亡
变量所在的地方叫做内存,管理变量,也就是内存管理。
在C及C++中,程序员通常需要手动进行内存管理,但这种做法可能会衍生出许多BUG,而Java等语言则引入了自动内存管理————垃圾回收,使得内存管理不必依靠人工,不得不说这是程序员的一大福音。
垃圾回收(GC),在百度中的解释如下:
一个跟踪过程,它传递性地跟踪指向当前使用的对象的所有指针,以便找到可以引用的所有对象,然后重新使用在此跟踪过程中未找到的任何堆内存。公共语言运行库垃圾回收器还压缩使用中的内存,以缩小堆所需要的工作空间。
应用
Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,Java中的对象不再有“作用域”的概念,只有对象的引用才有“作用域”。垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。回收机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收。
Java 程序员不用担心内存管理,因为垃圾收集器会自动进行管理。要请求垃圾收集,可以调用下面的方法之一:
System.gc()
Runtime.getRuntime().gc()
简单来说就是有这么一个机制,这个机制会在合适的时间去内存中巡视一圈,将不再被需要的变量清除掉,释放被占用的内存资源以供新的变量使用。
这听上去很简单,但深入的去了解它你将会得到一本厚厚的内存管理规则。
2. 如何消亡
上一节是关于变量“什么时候没的”,这一节简单描述一下变量的“死因”,怎么没的。
垃圾回收器要想进行它的回收工作,那么它必须有一个回收目标,回忆一下游戏里的场景吧,首先扫描所有进入视线的目标,然后分析是否是敌人或攻击目标,然后进行攻击。垃圾回收器的工作流程也是如此。
那么如何判定某个变量是否是执行目标呢?
这就要提到GC算法了,简单了解一下这些算法吧:
(1) 引用计数算法
从字面意义就能看出这个算法是根据变量被引用的数量计算的,当某个变量在某个时刻没有任何引用的时候,即引用计数为0,那么该变量将会被回收。
(2)可达性分析算法
将所有的变量之间的引用关系绘制为一张关系图,以变量为节点,以引用关系为边,当某个节点与根节点之间没有路径可达时,则认为该变量无效,将被回收。
(3)标记清除算法
标记-清除算法分为标记和清除两个阶段。该算法首先从根集合进行扫描,对存活的对象对象标记,标记完毕后,再扫描整个空间中未被标记的对象并进行回收。
(4)分代收集算法
这个算法将变量分为新生代、中生代、老生代和永久代,每次GC执行时都会对变量重新判定,对于新生代的变量关注较多,一个变量每撑过一轮GC,都将获得晋升机会。
3. 总结
这一篇的内容很少,只是粗浅的写了一点关于垃圾回收的常识,不至于让你一听到GC、垃圾回收就一头雾水。如果要深入了解,可以去搜索其他的博文,或者阅读一本关于JVM虚拟机内存回收的书籍。