java in a nutshell 笔记2
?
内存回收
?
?
Java解释器很清楚地知道它取得了哪些对象与数组,它也知道各个局部变量调用了哪些对象和数组以及那些对象或数组又调用了哪些其他的对象和数组。因此,解释器当然会知道对象何时已不再被其他的变量或对象所使用。当解释器找到这样的对象时,它知道可以安全地回收该对象所占用的内存。内存回收也可以侦测并撤销对象之间的循环(cycle)。循环是指某些对象之间有相互的引用,但并没有被其他操作中的对象所引用。任何这样的循环都会被回收。
?
不同的VM在处理内存回收的方式上本来就会有所不同。这是很合理的,内存回收是以一个低优先权的线程来执行的,所以在没有其他的事情要做时才会执行它大部分的操作,例如在等待用户输入数据的空闲时间。内存回收被当成高优先权来执行的唯一情况(也就是实际上真的会使系统崩溃的时候),就是可用的内存变得非常非常少的时候。但这并不会时常发生,因为这个低优先权的线程会在后台不停地清除不需要的对象。
?
JAVA中的内存泄漏
?
Java所支持的内存回收可大幅降低内存泄漏(memory leak)的发生率。内存泄漏会发生在内存已经被分配但却没有被回收时。刚开始时,你也会认为内存回收可以预防内存泄漏的原因,是因为它会回收所有不再被使用到的对象。然而,在JAVA里,如果一个对不再被使用的对象的有效引用被闲置时,内存泄漏的情形仍然会发生。例如,当一个method执行了很久(甚至会一直执行下去),在那个method中的局部变量所保留的对象引用可能会比实际所需要的时间还长。以下的程序代码可作说明:
?
public static final double PI = 3.14159265258979323846
?
?
现在,在PlaneCircle中的程序代码可以通过PlaneCircle.PI或表达式PI来使用这个更为精确的数字了,他也可以通过表达式super.PI与Circle.PI来引用旧的数值。请注意,PlaneCircle所继承的area()与circumference()方法是定义于Circle类,所以它们要使用Circle.PI,即使该值已经被PlaneCircle.PI隐含了。