文章目录

  • 前言
  • 了解finalize之前需要知道三点
  • (用途1)finalize()方法释放本地方法申请的内存
  • gc和finalize都不保证一定发生
  • (用途2)finalize作为终结条件

前言

话说在最前面:finalize方法的用途有两个:1.finalize()方法释放本地方法申请的内存;2.作为终结条件

Java中有垃圾回收,可以对new出来且不再使用的对象进行回收,
但是Java中有些情况下,申请内存不同通过new进行的!这种情况下垃圾回收就无法进行内存回收了
这种时候finalize()方法就会发挥它的作用,对这部分特殊申请的内存进行内存回收处理!


了解finalize之前需要知道三点

  1. Java中的对象不想C++中的对象,是可能不被垃圾回收的;(如果C++的代码没问题,申请的内存是一定要释放的,但是Java中的对象如果没达到条件,是不会被GC的)
  2. Java中的垃圾回收不等于C++中的析构函数;(Java并没有提供相关析构函数的概念,垃圾是自动回收的,不需要手动创建一个执行清理工作的方法)
  3. 垃圾回收只与内存有关;(Java中的垃圾回收只针对不再使用的内存,因此垃圾回收的任何行为(以及finalize方法)都必须只跟内存回收有关)

(用途1)finalize()方法释放本地方法申请的内存

  • finalize方法涉及到一种特殊的申请对象存储空间的方式(并不是一般的通过new来申请)。
  • 这种情况发生在Java中使用本地方法的时候(因为本地方法使用的是C或者C++来实现的),在本地方法中,C语言会调用malloc()函数来申请分配存储空间,而且除非调用了free()函数,不然是不会释放内存空间的(会导致内存泄漏)。
  • 因此在finalize()方法中进行调用了本地方法中的(C语言的)free()方法释放了malloc申请的内存空间。

gc和finalize都不保证一定发生

  • 在C++中,如果创建了一个局部对象,那么这个局部对象会存储在栈中,跟随方法的结束而销毁;C++如果通过new来创建对象,当使用结束的时候需要通过delete方法来调用析构函数,来讲new出来的内存空间释放掉,不过没有delete方法,那么析构函数永远不会被调用,那么就导致了内存泄漏。
  • 相反,Java中首先没有局部对象的概念,在HotSpot虚拟机中没有栈上分配的概念,因此对象都是在堆中通过new的方式申请的内存;其次Java中没有析构函数和delete的概念,但是Java有GC垃圾回收器。这样的话就比较方便了,GC会在Java运行时内存面临耗尽的情况下,对内存空间进行垃圾回收或者finalize。
  • 这样也就说明了,垃圾回收和finalize并不是一定能发生的,如果内存状况良好,或者没有垃圾,就可能不发生gc和finalize

(用途2)finalize作为终结条件

  • finalize方法绝对不可以直接调用,因此可能使用finalize方法的情景就少了,但是finalize还有别的用处!
  • 也就是将finalize方法当做对象的终结条件,进行验证!
  • 举个例子,一个对象如果我们不使用了,我们希望的是它能够被gc掉,但是可能这个对象中会存在一些调用,导致这个对象并不能被当做垃圾顺利的gc掉,太多的话会导致内存在漏严重,并且往往这些代码上的缺陷非常的难发现,这个时候就可以使用finalize方法来发现这种现象是否存在。
  • 尽管finalize方法不能被显式的调用,但是我们能够通过finalize方法作为检查对象终结的条件,发现代码上的缺陷,找到问题所在!这个用法很关键!

举个代码上的例子:

  • 假设每个被new出来的Solution对象被垃圾回收的终结条件是:status为false;(说人话就是对象的status为false才会被gc,如果为true的话就不会被gc)
  • 在mian方法中,new了两个对象,其中一个将status改为了false,但是另一个假如忘记修改状态了。
  • 这个时候finalize作为终结条件,就可以发现这个问题(发现要gc的对象没有更改状态,并打印)(如下代码所示)
class Solution {boolean status = false;public Solution(boolean status) {this.status = status;}public void setStatusFalse(){this.status = false;}//这里重写了finalize方法@Overrideprotected void finalize() throws Throwable {if (this.status){System.out.println("error:内存泄漏");}}public static void main(String[] args) {Solution solution = new Solution(true);solution.setStatusFalse();new Solution(true); // 忘记更改状态System.gc(); //强制进行full gc}
}

输出:

这个时候我们就可以根据打印的输出,检查一下是不是写代码有bug,导致有对象并没有达到终结条件。


【end】

【Java编程思想】finalize方法的真正用途?相关推荐

  1. java 析构函数_《JAVA编程思想》5分钟速成:第5章(初始化和清理)

    第五章.初始化和清理 前言 1.初始化顺序(静态成员.非静态成员,构造器.父类构造器)的排序: 2.构造器(constructor)是否可被重写(override)? 3.final, finally ...

  2. Java编程思想 (1~10)

    [注:此博客旨在从<Java编程思想>这本书的目录结构上来检验自己的Java基础知识,只为笔记之用] 第一章 对象导论 1.万物皆对象 2.程序就是对象的集合 3.每个对象都是由其它对象所 ...

  3. 关于java中的finalize()方法

    关于finalize()方法,之前了解的并不是很多,看<java编程思想>时才对此有所了解,之后我又看了些博客,稍微总结了一下finalize()方法: java提供finalize()方 ...

  4. 《Java编程思想》读书笔记一

    很早之前就买了<Java编程思想>这本书,初学时看这本书看的云里雾里的,实在费劲,就放在一边垫桌底了.感觉这本书是适合C/C++程序员转行到Java学习的一本书,并不适合零基础的初学者去看 ...

  5. Java编程思想 第四版 读书笔记巩固基础,完善知识框架。

    Java编程思想读书笔记 此笔记仅仅是作者的阅读此书时,发现自己错误认识和不牢固的知识,用来完善作者的知识框架,其列出重点不具有参考性,代码也是为了省工作量,简写代码,能看懂即可,语法并不规范 第一章 ...

  6. 《Java编程思想》读书笔记01-初始化与清理

    开篇 最近在看Java编程思想,想把Java SE部分重新巩固一下.由于之前看过两遍遍<Java疯狂讲义>,但是看过以后很多东西就忘记了,所以想记录一下学习Java SE的过程与重点.初步 ...

  7. Java编程思想第四版学习总结

    Java编程思想第四版学习总结 文章目录 Java编程思想第四版学习总结 第 1 章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 实现方案的隐藏 1.4 方案的重复使用 1.5 继承:重 ...

  8. 《Java编程思想》学习笔记(三)——初始化与清理

    一.初始化 初始化其实就是为变量分配内存空间,并确定其初始值的过程.想了解Java中初始化的各种情况,首先要了解Java中变量的类型.根据自己的理解,将Java中的变量类型分成以下几种,虽然可能不太准 ...

  9. Java编程思想学习笔记-第11章

    <?xml version="1.0" encoding="utf-8"?> Java编程思想学习笔记-第11章 Java编程思想学习笔记-第11章 ...

  10. Java编程思想第四版——第十五天

    2012-04-23 121-131/913 Java编程思想第四版--第十五天 5.5.3 终结条件 通常不能指望finalize(),必须创建其他的"清理"方法,并明确的调用它 ...

最新文章

  1. java在初始化过程_Java初始化过程
  2. lua进入压缩包_使用lua语言制作贪吃蛇游戏(love2d)(一)开发环境的搭建
  3. Ubuntu14.04 + KinectV2驱动安装 以及 Ros接口(基于网上方法试错 改进版)
  4. poj 2439 ArcticNetwork 最小生成树Kruskal、(Prim方法还没做
  5. iOS - UIView属性hidden, opaque, alpha, opacity的区别
  6. AUTOSAR标准与产业发展动态
  7. Android中MVC、MVP、MVVM具体解释
  8. VS中的lib和dll的区别和使用
  9. 信息量、信息熵、交叉熵、KL散度、JS散度、Wasserstein距离
  10. kotlin button_使用Kotlin和XML的Android Button
  11. 使用Kotlin编写Gradle插件
  12. html5怎么设置年月日选择框,HTML5文件选择框(各种类型)
  13. 奇迹服务器如何修改爆率,奇迹萌新教程系列-奇迹装备是否掉落配置调整
  14. 如何用Qlikview在dashboard中创建条形图时,统计时忽略空值
  15. linux mysql changed limits_ubuntu下mysql提示Changed limits: max_open_files:1024解决办法
  16. 【Linux】Linux关闭防火墙、关机重启和查看系统运行级别
  17. 单相全桥逆变原理及仿真实验
  18. 网页数据获取小技巧(小白)
  19. 解决:Plug-in org.eclipse.wst.jsdt.ui was unable to instantiate class org.eclipse.wst.jsdt.inte
  20. 好心情与爱谛科技战略合作签约,开启精神疾病定量治疗新篇!

热门文章

  1. 如何收割淘宝逛逛人群
  2. 社会信用代码 验证php,PHP校验信用卡号实例
  3. Java命令里面的EQ、NE、GT、LT、GE、LE分别代表含义
  4. js如何截取某个字符串前面或者后面的内容
  5. 台式电脑计算机能创建新磁盘吗,旧机械硬盘可以装新电脑上吗?台式电脑加新/旧机械硬盘+分区教程(2)...
  6. 可以打开html文件的app,【iOS】跳转App以及用其他软件打开本地文件
  7. windows搭建NTP时钟服务器(win xp、7、8、10)
  8. 阿里巴巴工程师为什么用寻找第83行代码向代码致敬
  9. 推荐 | 一个统计硕士的深度学习算法工程师的成长之路
  10. angular的js跳转使用get传值