---《java编程思想》 读书笔记
--- 2017/3/15java
读《java编程思想》读到初始化与清理一章,文中说起java的finalize()方法,联想到了C++的析构函数。finalize()方法与析构函数存在自然差异,这种差异源于语言自己机制的不一样。c++
在C++中,对象是能够在栈上分配的,也能够在堆上分配。在栈上分配的对象,也就是函数的局部变量,当超出块的"}"时,生命期便结束了。在堆上分配的对象,使用delete的时候,对象的生命期也就结束了。所以在C++中,对象的内存在哪一个时刻被回收,是能够肯定的(假设程序没有缺陷)。java秉承一切皆为对象的思想,对象仅能经过new来建立,所以java的对象是在堆上分配的内存。这些堆上的对象,若是没有做用了(无引用指向它),将等待垃圾回收器来回收其占用的内存。而垃圾回收期什么时候运行,没法提早预知,甚至有的时候直到程序退出都没有进行垃圾回收,程序所占内存直接由操做系统来回收。因此在java中,对象的内存在哪一个时刻回收,取决于垃圾回收器什么时候运行。所以,C++与java中,对无用对象的回收时间是不一样的。程序员
一旦C++的对象要被回收了,在回收该对象以前对象的析构函数将被调用,而后释放对象占用的内存;而java中编程
一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用其finalize()方法, 而且在下一次垃圾回收动做发生时,才会真正的回收对象占用的内存(《java 编程思想》)函数
可见在java中,调用GC不等于真正地回收内存资源,并且在垃圾回收中对象存在状态的变化。操作系统
C++的析构函数用来作一些必要的工做,例如释放掉指针成员所指向的对象所占的内存,由于C++没有java的垃圾回收器,全部new出来的对象,都要显式地delete掉,避免内存泄漏。《Effective C++》中说起,基类须要将析构函数声明为virtual函数,这是为了能够经过子类对象指针正确地释放掉基类的资源。总的来讲,在C++中,析构函数和资源的释放息息相关,能不能正确处理析构函数,关乎可否正确回收对象内存资源。 在java中,全部的对象,包括对象中包含的其余对象,它们所占的内存的回收都依靠垃圾回收器,所以不须要一个函数如C++析构函数那样来作必要的垃圾回收工做。固然存在本地方法时须要finalize()方法来清理本地对象。在《java编程思想》中说起,finalize()方法的一个做用是用来回收“本地方法”中的本地对象——C/C++代码所分配的内存,因为这部分的内存只能由delete/free来释放,所以能够放在finalize()方法中来作。在实际生产环境中,我较少(或说基本没有)看到java类实现了finalize()方法。能够说java最大程度地弱化了内存管理对应用程序员的束缚,而c++则对此要求严格多了。.net
另外,看到了两篇介绍java对象回收流程的文章:http://www.javashuo.com/article/p-vodmhnbo-w.html http://blog.csdn.net/rsljdkt/article/details/12242007
这些内容应该是在JVM的书籍中有涉及,这又是值得研究的一个点了。指针