java的finalize()方法与C++的析构函数

---《java编程思想》 读书笔记 --- 2017/3/15

读《java编程思想》读到初始化与清理一章,文中提及java的finalize()方法,联想到了C++的析构函数。finalize()方法与析构函数存在天然差别,这种差别源于语言本身机制的不同。

在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++则对此要求严格多了。

另外,看到了两篇介绍java对象回收流程的文章:https://my.oschina.net/u/1412027/blog/181710 http://blog.csdn.net/rsljdkt/article/details/12242007 这些内容应该是在JVM的书籍中有涉及,这又是值得研究的一个点了。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java爬坑系列

Java 强引用

不要被这个强字吓到,以为这个引用就很厉害,其实强引用就是程序中使用的一般引用类型。举个简单的栗子:

872
来自专栏xingoo, 一个梦想做发明家的程序员

Java程序员的日常—— 《编程思想》关于类的使用常识

Java虽然利用JVM,让程序员可以放心大胆的使用,可是仍然会出现内存泄露等问题。世上没有绝对的银弹,因此也不能完全把所有的任务都交给JVM,了解Java中的...

1826
来自专栏菜鸟计划

angularjs filter详解

过滤器(filter)正如其名,作用就是接收一个输入,通过某个规则进行处理,然后返回处理后的结果。 主要用在数据的格式化上,例如获取一个数组中的子集,对数组中的...

3538
来自专栏nnngu

经典Java面试题收集

2、访问修饰符public,private,protected,以及不写(默认)时的区别?

94513
来自专栏Vamei实验室

Python深入06 Python的内存管理

语言的内存管理是语言设计的一个重要方面。它是决定语言性能的重要因素。无论是C语言的手工管理,还是Java的垃圾回收,都成为语言最重要的特征。这里以Python语...

2179
来自专栏喵了个咪的博客空间

zephir-(5)类型

#zephir-类型# ? ##前言## 先在这里感谢各位zephir开源技术提供者 Zephir既可以使用动态类型也可以使用静态类型,这是zephir独特的一...

3479
来自专栏Java帮帮-微信公众号-技术文章全总结

【Java案例】九九乘法表

案例描述 输出九九乘法口诀表,如图1.4所示。 ? 图1.4 九九乘法口诀表 案例分析 观察九九乘法口诀表,可以得出图表的规律:总共有9行,第几行就有几个表达...

3519
来自专栏张善友的专栏

检查Python对象

编程环境中的对象很象现实世界中的对象。实际的对象有一定的形状、大小、重量和其它特征。实际的对象还能够对其环境进行响应、与其它对象交互或执行任务。计算机中的对象试...

18610
来自专栏云霄雨霁

Java--类和对象之初始化和清除

965
来自专栏微信公众号:Java团长

Java知识点集锦

答:不是。Java中的基本数据类型只有8个:byte、short、int、long、float、double、char、boolean;除了基本类型(primi...

921

扫码关注云+社区