您现在的位置是: 首页 > 成语谜语 成语谜语

finalize_finalized

ysladmin 2024-06-03 人已围观

简介finalize_finalized       对于finalize的问题,我有一些了解和研究,也可以向您推荐一些专业资料和研究成果。希望这对您有所帮助。1.

finalize_finalized

       对于finalize的问题,我有一些了解和研究,也可以向您推荐一些专业资料和研究成果。希望这对您有所帮助。

1.finalize 和gc的区别

2.为什么在Java中不使用finalize方法

3.谈谈final, finally, finalize的区别。

4.为什么Finalize不能重写

5.android开发中Final、finally、finanlize()的区别是什么?

finalize_finalized

finalize 和gc的区别

       gc 只能清除在堆上分配的内存(纯java语言的所有对象都在堆上使用new分配内存),而不能清除栈上分配的内存(当使用JNI技术时,可能会在栈上分配内 存,例如java调用c程序,而该c程序使用malloc分配内存时).因此,如果某些对象被分配了栈上的内存区域,那gc就管不着了,对这样的对象进行 内存回收就要靠finalize().

       举个例子来说,当java 调用非java方法时(这种方法可能是c或是c++的),在非java代码内部也许调用了c的malloc()函数来分配内存,而且除非调用那个了 free() 否则不会释放内存(因为free()是c的函数),这个时候要进行释放内存的工作,gc是不起作用的,因而需要在finalize()内部的一个固有方法 调用它(free()).

       finalize的工作原理应该是这样的:一旦垃圾收集器准备好释放对象占用的存储空间,它首先调用finalize(),而且只有在下一次垃圾收集过程中,才会真正回收对象的内存.所以如果使用finalize(),就可以在垃圾收集期间进行一些重要的清除或清扫工作.

为什么在Java中不使用finalize方法

       区别是:无论是否抛出异常,finally代码块都会执行,它主要是用来释放应用占用的资源。finalize()方法是Object类的一个protected方法,它是在对象被垃圾回收之前由Java虚拟机来调用的。

       finally:在异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)。

       finalize:方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。注意:finalize不一定被jvm调用,只有当垃圾回收器要清除垃圾时才被调用。

谈谈final, finally, finalize的区别。

       Java提供finalize()方法,垃圾回收器准备释放内存的时候,会先调用finalize()。

       (1).对象不一定会被回收。

       (2).垃圾回收不是析构函数。

       (3).垃圾回收只与内存有关。

       (4).垃圾回收和finalize()都是靠不住的,只要JVM还没有快到耗尽内存的地步,它是不会浪费时间进行垃圾回收的。

       有时当撤消一个对象时,需要完成一些操作。例如,如果一个对象正在处理的是非Java 资源,如文件句柄或window 字符字体,这时你要确认在一个对象被撤消以前要保证这些资源被释放。为处理这样的状况,Java 提供了被称为收尾(finalization )的机制。使用该机制你可以定义一些特殊的操作,这些操作在一个对象将要被垃圾回收程序释放时执行。

       要给一个类增加收尾(finalizer ),你只要定义finalize ( ) 方法即可。Java 回收该类的一个对象时,就会调用这个方法。在finalize ( )方法中,你要指定在一个对象被撤消前必须执行的操作。垃圾回收周期性地运行,检查对象不再被运行状态引用或间接地通过其他对象引用。就在对象被释放之前,Java 运行系统调用该对象的finalize( ) 方法。

       finalize()方法的通用格式如下:

       protected void finalize( )

       {

       // finalization code here

       }

       其中,关键字protected是防止在该类之外定义的代码访问finalize()标识符。该标识符和其他标识符将在第7章中解释。

       理解finalize( ) 正好在垃圾回收以前被调用非常重要。例如当一个对象超出了它的作用域时,finalize( ) 并不被调用。这意味着你不可能知道何时——甚至是否——finalize( ) 被调用。因此,你的程序应该提供其他的方法来释放由对象使用的系统资源,而不能依靠finalize( ) 来完成程序的正常操作。

       注意:如果你熟悉C ,那你知道C 允许你为一个类定义一个撤消函数(destructor ),它在对象正好出作用域之前被调用。Java不支持这个想法也不提供撤消函数。finalize() 方法只和撤消函数的功能接近。当你对Java 有丰富经验时,你将看到因为Java使用垃圾回收子系统,几乎没有必要使用撤消函数。

       理解finalize()-析构函数的替代者

       by Tim Gooch

       在许多方面,Java 类似于 C++。Java 的语法非常类似于 C++,Java 有类、方法和数据成员;Java 的类有构造函数; Java 有异常处理。

       但是,如果你使用过 C++ 会发现 Java 也丢掉一些可能是你熟悉的特性。这些特性之一就是析构函数。取代使用析构函数,Java 支持finalize() 方法。

       在本文中,我们将描述 finalize() 与 C++ 析构函数的区别。另外,我们将创建一个简单的 Applet 来演示 finalize() 是如何工作的。

       最终的界限

       与 Java 不同,C++ 支持局部对象(基于栈)和全局对象(基于堆)。因为这一双重支持,C++ 也提供了自动构造和析构,这导致了对构造函数和析构函数的调用,(对于堆对象)就是内存的分配和释放。

       在 Java 中,所有对象都驻留在堆内存,因此局部对象就不存在。结果,Java 的设计者觉得不需要析构函数(象 C++ 中所实现的)。

       取而代之,Java 定义了一个特殊的方法叫做finalize() ,它提供了 C++ 析构函数的一些功能。但是,finalize() 并不完全与 C++ 的析构函数一样,并可以假设它会导致一系列的问题。finalize() 方法作用的一个关键元素是 Java 的垃圾回收器。

       垃圾回收器

       在 C/C++、Pascal和其他几种多种用途的编程语言中,开发者有责任在内存管理上发挥积极的作用。例如,如果你为一个对象或数据结构分配了内存,那么当你不再使用它时必须释放掉该内存。

       在 Java 中,当你创建一个对象时,Java 虚拟机(JVM)为该对象分配内存、调用构造函数并开始跟踪你使用的对象。当你停止使用一个对象(就是说,当没有对该对象有效的引用时),JVM 通过垃圾回收器将该对象标记为释放状态。

       当垃圾回收器将要释放一个对象的内存时,它调用该对象的finalize() 方法(如果该对象定义了此方法)。垃圾回收器以独立的低优先级的方式运行,只有当其他线程挂起等待该内存释放的情况出现时,它才开始运行释放对象的内存。(事实上,你可以调用System.gc() 方法强制垃圾回收器来释放这些对象的内存。)

       在以上的描述中,有一些重要的事情需要注意。首先,只有当垃圾回收器释放该对象的内存时,才会执行finalize()。如果在 Applet 或应用程序退出之前垃圾回收器没有释放内存,垃圾回收器将不会调用finalize()。

       其次,除非垃圾回收器认为你的 Applet 或应用程序需要额外的内存,否则它不会试图释放不再使用的对象的内存。换句话说,这是完全可能的:一个 Applet 给少量的对象分配内存,没有造成严重的内存需求,于是垃圾回收器没有释放这些对象的内存就退出了。

       显然,如果你为某个对象定义了finalize() 方法,JVM 可能不会调用它,因为垃圾回收器不曾释放过那些对象的内存。调用System.gc() 也不会起作用,因为它仅仅是给 JVM 一个建议而不是命令。

       结论

       然而有益的是,Java 的自动垃圾回收器不会失去平衡。作为便利的代价,你不得不放弃对系统资源释放的控制。不象 C++ 中的析构函数,Java Applet 不会自动执行你的类中的finalize() 方法。事实上,如果你正在使用 Java 1.0,即使你试图强制它调用finalize() 方法,也不能确保将调用它。

       因此,你不应当依靠finalize() 来执行你的 Applet 和应用程序的资源清除工作。取而代之,你应当明确的清除那些资源或创建一个try...finally 块(或类似的机制)来实现。

       finalize方法是与Java编程中的垃圾回收器有关系。即:当一个对象变成一个垃圾对象的时候,如果此对象的内存被回收,那么就可以调用系统中定义的finalize方法来完成

       当然,Java的内存回收可以由JVM来自动完成。如果你手动使用,则可以使用上面的方法。

       举例说明:

为什么Finalize不能重写

       final是用来修饰名词的,即它是用来表达最终的某个东西的。比如,“最后的战役”,“最后的晚餐”,“最后的结局”之类的。

       finally是用来修饰名词以外的词的(经常是修饰动词用的),即它是用来表达最终的一个行为或动作的。比如“他最后还是来了”“你最后赢了没”“钱最终怎么算的”

       finalize是动词,它不修饰其他词,它就是表达了一种“了结,完成,完善,搞定”的一个行为。就比如“咱把这事了结了吧”“把题目做完”“把工作做完”

       三个词都跟“完结”有关,前两个只是表达某件事情已经完结时是什么样的。而第三个词,它的作用在于把一个没完结的东西变到已经完结的状态,是一种行为。

android开发中Final、finally、finanlize()的区别是什么?

       不能重写只是编译器干的事儿,实际上它就是想让你只能写析构函数,而写析构函数就相当于重写了Finalize。

       这只是一种设计方式。

       你可以改Assembly的代码,直接写IL,会发现是可以override的。

       你可以上网搜索一下Mono.cecil,有相关的内容。

       举个例子,按照C#的规范,一个类里面是不可能有两个方法名相同,参数相同,而仅仅是返回值不同的方法的,例如:

       public class MyClass

       {

        public string Foo()

        {

        }

        public int Foo()

        {

        }

       }

       直接写上述C#代码,编译无法通过,编译器会告诉你这两个方法签名是不明确的。

       但是如果是IL(即Assembly中编译后的内容),是可以有这么两个方法的。

       因为IL中描述的方法其实就是个方法的地址,根本不管你的方法是叫啥名字。只要知道地址,就能调用。

       ================================

       再补充一下,你可以自己做这个实验:

       首先写一个类:

        public class SampleClass

        {

        public SampleClass()

        {

        }

        ~SampleClass()

        {

        }

        }

       编译。

       然后使用Visual Studio自带的工具IL Disassembler,一般位于开始菜单的 Microsoft VisualStudio 2010(看你自己的安装版本)\Microsoft Windows SDK Tools\ 下面

       打开刚才编译好的dll或者exe,在左边会有一个类型列表,找到刚才写的SampleClass,点开"+",会看到下面有两个方法,

       一个是:.ctor:void() 这个其实就是构造函数

       另一个是:Finalize:void() 这个就是我们刚才写的析构函数。

       这说明什么呢?说明其实析构函数就是重载的Finalize。也就是编译器给我们玩儿的小把戏而已。

       再双击这个Finalize:void(),可以看到里面的IL代码:

       .method family hidebysig virtual instance void

        Finalize() cil managed

       {

        // Code size 14 (0xe)

        .maxstack 1

        .try

        {

        IL_0000: nop

        IL_0001: nop

        IL_0002: leave.s IL_000c

        } // end .try

        finally

        {

        IL_0004: ldarg.0

        IL_0005: call instance void [mscorlib]System.Object::Finalize()

        IL_000a: nop

        IL_000b: endfinally

        } // end handler

        IL_000c: nop

        IL_000d: ret

       } // end of method SampleClass::Finalize

       注意这一句:

       [mscorlib]System.Object::Finalize()

        IL_000a: nop

        IL_000b: endfinally

       其实就是在调用基类的(即object)的Finalize方法

       答案:final用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。

       finally是异常处理语句结构的一部分,表示总是执行。

       finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。

       今天关于“finalize”的讨论就到这里了。希望通过今天的讲解,您能对这个主题有更深入的理解。如果您有任何问题或需要进一步的信息,请随时告诉我。我将竭诚为您服务。