Java的一个重要特点就是具有一个垃圾回收器,并且能够自动回收垃圾,这又是Java相对于其他语言的优势。Java类的实例对象和数组所需的存储空间是在堆上分配的,解释器具体承担为类实例分配空间的工作。解释器在为一个实例对象分配完存储空间后,便开始记录该实例对象所占用的内存区域的使用个,一旦对象使用完毕,便将其会受到垃圾箱中。Java语言的垃圾回收机制解决了两个常见的应用程序错误:内存泄漏和无效内存的引用。
注:
(1)内存泄漏:用动态存储分配函数动态开辟的空间,在使用完毕之后没有得到释放,结果导致一直占据该内存单元,直到程序运行结束。就好比在Java中申明了数组之后,没有为该数组申明一个指向该数组的引用变量,导致该数组变成了垃圾。
(2)无效内存的引用:内存越界。(求具体含义)
在Java程序运行过程中,一个垃圾回收器会不定时地被唤起检查是否有不再被使用的对象,并释放它们占用的内存空间。垃圾回收器的启用不由程序员控制,也无规律可循,并不会一产生了垃圾,它就被唤起,甚至有可能到程序终止,它都没有启动的机会。因此Java垃圾回收机制并不是一个很可靠的机制。但这或许不是意见坏事,因为启动垃圾回收机制需要占用系统资源,给系统带来负担。
Java垃圾回收常用的两种策略:
(1)复制式回收策略:这种方法的执行过程是先将正在运行的程序暂停,然后把正在被使用的所有对象从它们所在的堆内存里复制到另一个堆内存,那些不再被使用的对象所占据的内存空间就被释放掉。这种机制需要两块堆内存用于将内存中的内容搬运复制,这就需要维护所需内存数量的两倍的内存空间,更麻烦的是即使程序中只产生少量垃圾甚至没有垃圾,回收器仍然会把堆内存里的内容复制到另一块堆内存中,这就是得这种方法的效率比较低下,为了解决这种问题就有了下面的方法。
(2)自省式:这种方法回收器会检测所有正在使用的兑现个,并为它们标注,完成这项工作后再将所有不再被使用的对象所占据的内存空间一次性释放掉。这种方法的速度仍让比较慢,不过如果程序中只是产生了少量垃圾甚至不产生垃圾时,这种方法就有一定的优势了。
垃圾回收的有关代码
(1)finalize()函数的作用与C++中的析构函数类似,但是无法保证每个对象的finalize()函数都会最终被调用。如:
class Person
{
public void finalize()
{
System.out.println("the object is going");
}
public static void main(String[] args)
{
new Person();
new Person();
new Person();
System.out.println("the program is ending");
}<pre name="code" class="java"><span style="font-family: Arial, Helvetica, sans-serif;">}</span>
编译运行后的结果是:
the program is ending!
在上面的程序中,产生了三个Person类的对象,而且三个对象在System.out.println("the program is ending");语句之前已经变成了垃圾,但是可以看到的是finalize()函数并没有被调用。
(2)System.gc()函数为了拟补finalize()函数的缺陷,System.gc()函数能够强制启动垃圾回收器来回收垃圾。如:
class Person
{
public void finalize()
{
System.out.println("the object is going");
}
public static void main(String[] args)
{
new Person();
new Person();
new Person();
System.gc();
System.out.println("the program is ending");
}
}
编译运行后的结果是:
the object is going
the object is going
the object is going
the program is ending
这就是我所知道的Java垃圾回收知识点,如有其他请补充分享哈!