- 西柚不是西游
-
final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
finally是异常处理语句结构的一部分,表示总是执行。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等
请说一下final,finally和finalize的区别
final修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承例如:String类、Math类等。将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为final的方法也同样只能使用,不能重写,但是能够重载。 使用final修饰的对象,对象的引用地址不能变,但是对象的值可以变!finally在异常处理时提供 finally 块来执行任何清除操作。如果有finally的话,则不管是否发生异常,finally语句都会被执行。一般情况下,都把关闭物理连接(IO流、数据库连接、Socket连接)等相关操作,放入到此代码块中。finalize方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要清理工作。finalize() 方法是在垃圾收集器删除对象之前被调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。 一般情况下,此方法由JVM调用,程序员不要去调用!2023-06-20 19:38:082
为什么在Java中不使用finalize方法
Object的中的方法finalize(),格式如下protected void finalize( ) throws Throwable{...............}不能用的原因是它使用了修饰符protected,从下面可以看出protected在不同包内是不能用的,你可以在类中调用方法,但是实例化的对象是肯定不用想了。作用域 当前类 同一package 子孙类 其他package public √ √ √ √ protected √ √ √ × friendly √ √ × × private √ × × ×2023-06-20 19:38:152
finally代码块和finalize()方法有什么区别?
无论是否抛出异常,finally代码块都会执行,它主要是用来释放应用占用的资源。finalize()方法是Object类的一个protected方法,它是在对象被垃圾回收之前由Java虚拟机来调用的。2023-06-20 19:38:222
finish与finalize区别
Finish表示过去某个时候着手做的事已经做完,或者表示对已经做完的事进行精密加工。例:As soon as he had finished, Jenny told him she wanted to go home. 他一讲完,珍妮就告诉他说她想回家。 This machine part needs surface finishing. 这个机械零件需要精密加工。 Finalize 词根fin=to end(结束) v.把(计划,稿件等)最后定下来,定案,主要用于官方文字,意思是把办理了很久或搁置了了的事情做一了结。例如:to finalize a budge estimate(完成预算估计.例:同时,工业设计师和工程师一道来完成部件和组装部分的工作。At the same time, industrial designers work with engineers to finalize components and assembly.他说,关于拟议中访问的计划还需作最后肯定。He said he had got to finalize the plan for the proposed visit.一个现成的例子就是,在欧洲央行最近的一项协议中,跨国界交易和资本流动的成本和银行佣金率降低的最后期限被。The recent agreement clinched by the ECB to finalize the deadline for lowering the charges and commission rates for trans-border transactions and capital transfer can serve as a case in point.2023-06-20 19:38:301
finalise和finalize的区别,求老师帮帮忙,谢谢啦,(*^__^*)
你好!finalise 和 finalize用法和意思没什么区别,但在英国人们基本用finalise,而在美国则大多用finalize。所以从这点来说,finalise 是 finalize 的根,finalize 是从 finalise 发展出来的。以上仅供参考!2023-06-20 19:38:381
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(),就可以在垃圾收集期间进行一些重要的清除或清扫工作.2023-06-20 19:38:451
谁帮忙解释final/finally/finalize的含义?
final 就是最终的意思~final类就不能被继承,final函数就不能被重写,final变量就不变。finally 就是try catch 后必须执行的语句finalize 是在GC工作清理对象时执行的东西2023-06-20 19:38:521
final 、finally、finalize 三个关键字都可以在类的内部使用??对还是错?
对。一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承.因此一个类不能既被声明为 abstract的,又被声明为final的.将变量或方法声明为final,可以保证它们在使用中不被改变.被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改.被声明为final的方法也同样只能使用,不能重载finally?再异常处理时提供 finally 块来执行任何清除操作.如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话).finalize?方法名.Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作.这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的.它是在 Object 类中定义的,因此所有的类都继承了它.子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作.从这些描述就可以看出来,final可以用在变量上,自然可以用在类内部。finally本来就是处理异常的,用哪里都行,另外那个也是这样2023-06-20 19:39:001
如何在java程序结束时有效及时的调用finalize
一个对象被判定符合GC条件以后,在GC之前finalize()方法会被调用,所以基本可以说其被回收了。但是有种特殊情况:就是在finalize()中重新让对象不符合GC条件,这样对象就避开了一次GC,这时对象就没有被回收,下次对象再次符合条件的时候finalize()也不会被调用,但是它还是被回收了ps:finalize()只能被调用一次2023-06-20 19:39:071
java中finalize()方法的使用
设计一个对象重生的代码来演示,如下:具体解析如下:为方便起见, 把a,b两个变量所指的内存空间就叫做a和b。A a = new A(new B("allen" , 20)) ; //此时a和b都是reachable, unfinalized状态。a = null ;这之后, a和b的状态会在某一个时刻变成unreachable, unfinalized或者a和b直接变成f-reachable, unfianlized。然后在某个时刻,GC检测到a和b处于unfinalized状态,就将他们添加到F-queue,并将状态改为f-reachable finalizable。之后分两种情况:1、 GC从F-queue中首先取出a, 并被某个线程执行了finalize(), 也就相当于被某个活动的线程持有, a状态变成了reachable, finalized.。此时由于a被c对象所引用,所以之后不会变成unreachable finalized而被销毁(重生) 与此同时,b由于一直被a所引用,,所以b的状态变成了reachable, finalizable.。然后在某个时刻被从F-queue取出, 变成reachable, finalized状态。2、GC从F-queue中首先取出b,并被某个线程执行了finalize(), 状态变成reachable finalized. 然后a也类似, 变成reachable finalized状态, 并被c引用,重生。扩展资料:尽量避免使用finalize():1、finalize()不一定会被调用, 因为java的垃圾回收器的特性就决定了它不一定会被调用。2、就算finalize()函数被调用, 它被调用的时间充满了不确定性, 因为程序中其他线程的优先级远远高于执行finalize()函数线程的优先级。也许等到finalize()被调用, 数据库的连接池或者文件句柄早就耗尽了。3、如果一种未被捕获的异常在使用finalize方法时被抛出,这个异常不会被捕获,finalize方法的终结过程也会终止,造成对象出于破坏的状态。被破坏的对象又很可能导致部分资源无法被回收, 造成浪费。4、finalize()函数和垃圾回收器的运行本身就要耗费资源, 也许会导致程序的暂时停止。参考资料:百度百科--finalize2023-06-20 19:39:171
为什么Finalize不能重写
不能重写只是编译器干的事儿,实际上它就是想让你只能写析构函数,而写析构函数就相当于重写了Finalize。这只是一种设计方式。你可以改Assembly的代码,直接写IL,会发现是可以override的。你可以上网搜索一下Mono.cecil,有相关的内容。举个例子,按照C#的规范,一个类里面是不可能有两个方法名相同,参数相同,而仅仅是返回值不同的方法的,例如:publicclassMyClass{publicstringFoo(){}publicintFoo(){}}直接写上述C#代码,编译无法通过,编译器会告诉你这两个方法签名是不明确的。但是如果是IL(即Assembly中编译后的内容),是可以有这么两个方法的。因为IL中描述的方法其实就是个方法的地址,根本不管你的方法是叫啥名字。只要知道地址,就能调用。================================再补充一下,你可以自己做这个实验:首先写一个类:publicclassSampleClass{publicSampleClass(){}~SampleClass(){}}编译。然后使用VisualStudio自带的工具ILDisassembler,一般位于开始菜单的MicrosoftVisualStudio2010(看你自己的安装版本)MicrosoftWindowsSDKTools下面打开刚才编译好的dll或者exe,在左边会有一个类型列表,找到刚才写的SampleClass,点开"+",会看到下面有两个方法,一个是:.ctor:void()这个其实就是构造函数另一个是:Finalize:void()这个就是我们刚才写的析构函数。这说明什么呢?说明其实析构函数就是重载的Finalize。也就是编译器给我们玩儿的小把戏而已。再双击这个Finalize:void(),可以看到里面的IL代码:.methodfamilyhidebysigvirtualinstancevoidFinalize()cilmanaged{//Codesize14(0xe).maxstack1.try{IL_0000:nopIL_0001:nopIL_0002:leave.sIL_000c}//end.tryfinally{IL_0004:ldarg.0IL_0005:callinstancevoid[mscorlib]System.Object::Finalize()IL_000a:nopIL_000b:endfinally}//endhandlerIL_000c:nopIL_000d:ret}//endofmethodSampleClass::Finalize注意这一句:[mscorlib]System.Object::Finalize()IL_000a:nopIL_000b:endfinally其实就是在调用基类的(即object)的Finalize方法2023-06-20 19:39:521
Java中Object类的finalize方法问题
finalize()存在以下问题:1.就算是重写了finalize(),并且不被你的程序引用到的情况下,也不能立即就被GC回收掉。 这是因为,GC后,为了执行finalize()方法,它被JavaVM的引用还残留着。2.不能保证GC后finalize()被执行。3.finalize()执行的顺序是不定的。举个极端的例子java.lang.System.gc();java.lang.System.runFinalization();java.lang.System.gc();就算这样也并不能保证Object被彻底回收。所以,一定一定不要去重写finalize(),然后期待Object被回收,这样反而容易内存泄漏。因为它并不能达到你想要的结果。2023-06-20 19:39:591
final,finally和finalize的区别是什么
三个虽然很相似 但是完全出于不同的概念和领域,也就是风马牛不相及的三个东西.final修饰符 修饰常量finally 用于捕获异常的最后输出finalize是垃圾回收机制里面的方法,目前基本所有公司都不用2023-06-20 19:40:061
java中finalize方法中的代码为什么不保证一定执行?
同意楼下的说法。java垃圾回收机制好好去理解理解。2023-06-20 19:40:163
f对象的finalize方法抛出异常会导致FinalizeThread退出吗?
首先,finalize()一定会被执行,但是并不总是那么及时,原因有二: 1、垃圾回收器并不总是工作,只有当内存资源告急时,垃圾回收器才会工作; 2、即使垃圾回收器工作,finalize方法也不一定得到执行,这是由于程序中的其他线程的优先级远远高于执行finalize()函数线程的优先级。 因此,当finalize还没有被执行时,系统的其他资源,比如文件句柄、数据库连接池等已经消耗殆尽,造成系统崩溃。第二,如果一种未被捕获的异常在使用finalize方法时被抛出,这个异常不会被捕获,finalize方法的终结过程也会终止,造成对象出于破坏的状态。第三,第二种情况已经是一种特例,还有其他的情况也会造成对象不会被销毁,从而浪费内存。第四,垃圾回收和finalize方法的执行本身就是对系统资源的消耗,有可能造成程序的暂时停止,因此在程序中尽量避免使用finalize方法。2023-06-20 19:40:232
java中的 finalize()中的语句为什么没执行?
finalize是会执行的,不过不是在你的方法执行完后,通常这样认为是错误的。那个方法的执行是在GC回收那个对象时执行。你的方法执行完了GC不一定就会回收那个对象。所以不能说不执行,而是不能控制它在什么时候执行。2023-06-20 19:40:311
怎样才能让finalize方法总会被调用评论
在释放对象占用的内存之前,垃圾收集器会调用对象的finalize()方法。一般建议在该方法中释放对象持有的资源。2023-06-20 19:40:391
f对象的finalize方法会执行多次吗?
在f对象的finalize方法里重新将当前对象赋值,变成可达对象,当这个f对象再次变成不可达时还会执行finalize方法吗?答案是否定的,因为在执行完第一次finalize方法后,这个f对象已经和之前的Finalizer对象剥离了,也就是下次GC的时候不会再发现Finalizer对象指向该f对象了,自然也就不会调用这个f对象的finalize方法了。2023-06-20 19:40:462
java中垃圾回收机制的原理
回收机制就是 当一些资源被创建使用之后或不在调用的话 就会变成垃圾,垃圾的话会占用空间,这时候就需要释放空间给其他程序使用,所以JAVA拥有自动垃圾回收机制,会在适当的时候自动调用垃圾回收 释放资源,程序员也可以手动调用释放资源等等。如:public class A {String str;public A(String str){ this.str=str;} public String toString(){ return str; } @Override protected void finalize() throws Throwable { System.out.println("我是"+str+".我被回收了.."); } public static void main(String[] args) { A a=new A("李四"); a=null; System.gc(); //运行结果 我是李四.我被回收了.. }}2023-06-20 19:40:545
我new一个object但是怎么调不成finalize这个方法啊,谁给我说下是什么原因?finalize这个方法能做什么啊
这个方法不是给你调的,是给GC回收垃圾时调的你没发现它是protected的么?!2023-06-20 19:41:082
C#中对象的销毁有三种方式Finalize,Dispose,GC。请大虾们描述三种方式的区别啊?
MSDN建议按照下面的模式实现IDisposable接口: 1 public class Foo: IDisposable2 {3 public void Dispose()4 {5 Dispose(true);6 GC.SuppressFinalize(this);7 }8 9 protected virtual void Dispose(bool disposing)10 {11 if (!m_disposed)12 {13 if (disposing)14 {15 // Release managed resources16 }17 18 // Release unmanaged resources19 20 m_disposed = true;21 }22 }23 24 ~Foo()25 {26 Dispose(false);27 }28 29 private bool m_disposed;30 }31 在.NET的对象中实际上有两个用于释放资源的函数:Dispose和Finalize。Finalize的目的是用于释放非托管的资源,而Dispose是用于释放所有资源,包括托管的和非托管的。在这个模式中,void Dispose(bool disposing)函数通过一个disposing参数来区别当前是否是被Dispose()调用。如果是被Dispose()调用,那么需要同时释放 托管和非托管的资源。如果是被~Foo()(也就是C#的Finalize())调用了,那么只需要释放非托管的资源即可。这是因为,Dispose()函数是被其它代码显式调用并要求释放资源的,而Finalize是被GC调用的。在GC调用的时候Foo所引用的其它 托管对象可能还不需要被销毁,并且即使要销毁,也会由GC来调用。因此在Finalize中只需要释放非托管资源即可。另外一方面,由于在 Dispose()中已经释放了托管和非托管的资源,因此在对象被GC回收时再次调用Finalize是没有必要的,所以在Dispose()中调用 GC.SuppressFinalize(this)避免重复调用Finalize。然而,即使重复调用Finalize和Dispose也是不存在问题的,因为有变量m_disposed的存在,资源只会被释放一次,多余的调用会被忽略过去。因此,上面的模式保证了:1、 Finalize只释放非托管资源;2、 Dispose释放托管和非托管资源;3、 重复调用Finalize和Dispose是没有问题的;4、 Finalize和Dispose共享相同的资源释放策略,因此他们之间也是没有冲突的。在C#中,这个模式需要显式地实现,其中C#的~Foo()函数代表了Finalize()。而在C++/CLI中,这个模式是自动实现的,C++的类析构函数则是不一样的。按照C++语义,析构函数在超出作用域,或者delete的时候被调用。在Managed C++(即.NET 1.1中的托管C++)中,析构函数相当于CLR中的Finalize()方法,在垃圾收集的时候由GC调用,因此,调用的时机是不明确的。在.NET 2.0的C++/CLI中,析构函数的语义被修改为等价与Dispose()方法,这就隐含了两件事情:1、 所有的C++/CLI中的CLR类都实现了接口IDisposable,因此在C#中可以用using关键字来访问这个类的实例。2、 析构函数不再等价于Finalize()了。对于第一点,这是一件好事,我认为在语义上Dispose()更加接近于C++析构函数。对于第二点,Microsoft进行了一次扩展,做法是引入了“!”函数,如下所示:1 public ref class Foo2 {3 public:4 Foo();5 ~Foo(); // destructor6 !Foo(); // finalizer7 };8“!”函数(我实在不知道应该怎么称呼它)取代原来Managed C++中的Finalize()被GC调用。MSDN建议,为了减少代码的重复,可以写这样的代码:1 ~Foo()2 {3 //释放托管的资源4 this->!Foo();5 }6 7 !Foo()8 {9 //释放非托管的资源10 }11对于上面这个类,实际上C++/CLI生成对应的C#代码是这样的:1 public class Foo2 {3 private void !Foo()4 {5 // 释放非托管的资源6 }7 8 private void ~Foo()9 {10 // 释放托管的资源11 !Foo();12 }13 14 public Foo() 15 {16 }17 18 public void Dispose()19 {20 Dispose(true);21 GC.SuppressFinalize(this);22 }23 24 protected virtual void Dispose(bool disposing)25 {26 if (disposing)27 {28 ~Foo();29 }30 else31 {32 try33 {34 !Foo();35 }36 finally37 {38 base.Finalize();39 }40 }41 }42 43 protected void Finalize()44 {45 Dispose(false);46 }47 }48由于~Foo()和!Foo()不会被重复调用(至少MS这样认为),因此在这段代码中没有和前面m_disposed相同的变量,但是基本的结构是一样的。并且,可以看到实际上并不是~Foo()和!Foo()就是Dispose和Finalize,而是C++/CLI编译器生成了两个Dispose 和Finalize函数,并在合适的时候调用它们。C++/CLI其实已经做了很多工作,但是唯一的一个问题就是依赖于用户在~Foo()中调 用!Foo()。关于资源释放,最后一点需要提的是Close函数。在语义上它和Dispose很类似,按照MSDN的说法,提供这个函数是为了让用户感觉舒服一点,因为对于某些对象,例如文件,用户更加习惯调用Close()。然而,毕竟这两个函数做的是同一件事情,因此MSDN建议的代码就是:1 public void Close()2 {3 Dispose(();4 }5 6 这里直接调用不带参数的Dispose函数以获 得和Dispose相同的语义。这样似乎就圆满了,但是从另外一方面说,如果同时提供了Dispose和Close,会给用户带来一些困惑。没有看到代码 细节的前提下,很难知道这两个函数到底有什么区别。因此在.NET的代码设计规范中说,这两个函数实际上只能让用户用一个。因此建议的模式是:1 public class Foo: IDisposable2 {3 public void Close()4 {5 Dispose();6 }7 8 void IDisposable.Dispose()9 {10 Dispose(true);11 GC.SuppressFinalize(this);12 }13 14 protected virtual void Dispose(bool disposing)15 {16 // 同前17 }18 }19这里使用了一个所谓的接口显式实现:void IDisposable.Dispose()。这个显式实现只能通过接口来访问,但是不能通过实现类来访问。因此:1 Foo foo = new Foo();2 3 foo.Dispose(); // 错误4 (foo as IDisposable).Dispose(); // 正确5----------------------------------以下是CSDN上一位高手的总结----------------------------------------------1、Finalize方法(C#中是析构函数,以下称析构函数)是用于释放非托管资源的,而托管资源会由GC自动回收。所以,我们也可以这样来区分 托管和非托管资源。所有会由GC自动回收的资源,就是托管的资源,而不能由GC自动回收的资源,就是非托管资源。在我们的类中直接使用非托管资源的情况很 少,所以基本上不用我们写析构函数。 2、大部分的非托管资源会给系统带来很多负面影响,例如数据库连接不被释放就可能导致连接池中的可用数据库连接用尽。文件不关闭会导致其它进程无法读写这个文件等等。 实现模型: 1、由于大多数的非托管资源都要求可以手动释放,所以,我们应该专门为释放非托管资源公开一个方法。实现IDispose接口的Dispose方法是最好的模型,因为C#支持using语句快,可以在离开语句块时自动调用Dispose方法。 2、虽然可以手动释放非托管资源,我们仍然要在析构函数中释放非托管资源,这样才是安全的应用程序。否则如果因为程序员的疏忽忘记了手动释放非托管资源, 那么就会带来灾难性的后果。所以说在析构函数中释放非托管资源,是一种补救的措施,至少对于大多数类来说是如此。 3、由于析构函数的调用将导致GC对对象回收的效率降低,所以如果已经完成了析构函数该干的事情(例如释放非托管资源),就应当使用SuppressFinalize方法告诉GC不需要再执行某个对象的析构函数。 4、析构函数中只能释放非托管资源而不能对任何托管的对象/资源进行操作。因为你无法预测析构函数的运行时机,所以,当析构函数被执行的时候,也许你进行操作的托管资源已经被释放了。这样将导致严重的后果。 5、(这是一个规则)如果一个类拥有一个实现了IDispose接口类型的成员,并创建(注意是创建,而不是接收,必须是由类自己创建)它的实例对象,则 这个类也应该实现IDispose接口,并在Dispose方法中调用所有实现了IDispose接口的成员的Dispose方法。 只有这样的才能保证所有实现了IDispose接口的类的对象的Dispose方法能够被调用到,确保可以手动释放任何需要释放的资源。2023-06-20 19:41:261
为什么垃圾回收器回收无用对象内存时调用finalize方法可能是对象复活还要调用?
在 Java 中,垃圾回收器在回收无用对象内存时,会调用对象的 finalize() 方法以便在对象释放内存之前完成一些清理工作。在 finalize() 方法中,可以对对象进行一些资源清理、关闭等操作,但是不能对其它对象进行引用,否则可能会导致对象复活。对象复活是指在对象的 finalize() 方法中,对该对象进行了一些操作,使得该对象重新被引用,从而避免了垃圾回收器对该对象的回收。如果在 finalize() 方法中对该对象进行了引用,则该对象不会被垃圾回收器回收,而是被认为是活动对象,从而继续存在于内存中。需要注意的是,对象复活并不是一种推荐的编程方式,因为它会导致内存泄漏和性能问题。在 Java 中,应该尽量避免使用 finalize() 方法,并使用 try-with-resources 或手动关闭资源等方式来进行资源清理和释放。2023-06-20 19:41:331
vb.net Close和Finalize 方法
Me.Close() frm.Show()调换两句.因me.close已把后面的frm.show给忽略了.2023-06-20 19:41:422
Java中的重写finalize和system.gc问题
嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯2023-06-20 19:41:502
finallize是java关键字吗
不是的,并且你写错了。finalize,它是一个方法名,在Obejct中定义的,所以,所有的类都有该方法finalize(),是需要清理什么的时候用的。final,是关键字。修饰一个变量时,该变量只能被赋值一次。修饰一个方法时,该方法不能被重写。finally,是关键字。与try(){}catch(){}finally(){}一同使用,不管try,catch中的代码是否异常,都会执行finally代码。2023-06-20 19:41:581
Java终止函数深度分析
Java终止函数是什么? 对于对象而言 Java 终止函数履行最后的确认工作 这与Java 构造函数是相反的 Java 构造函数创建以及初始化了一个Java类实例 当一个对象不在被需要以及这些资源必须被用于其它对象的时候 在一个类实例或者发行的系统资源 比如说文件描述符或者网络 <;接口连接上 Java 终止函数可以被用来清除任务 你不需要证据或者为终止函数返回任何值 遗憾的是当一个类或者接口被载入的时候 目前的Java语言的介绍中没有任何关于终止函数用于Java类或者接口的解释 让我们进一步研究一下java lang对象的终止函数finalize()方法 提供一个方法实例 (如何使用PHP 中的Clone函数) protected void finalize() throws Throwable 当一个Java对象不再被需要的时候 这个对象原先占有的空间就会期望能够自动的由Java回收工具进行回收利用 这在Java中有着显著的差异 并且在大多数的结构性程序语言 比如说C语言中 是不常见的 如果一个类实例实施终止函数finalize()方法 它所占用的空间就不能及时的被回收工具重新回收利用 最坏的情况是也许它根本就不再被回收了 任何实施终止函数finalize() 方法的类实例都经常调用终止对象 当它们不再被引用的时候 它们不能立即被Java回收工具回收 为最终程序Java回收工具将对象附加到指定的队列 通常是由一个指定的线性程序执行的 在一些Java虚拟机上被称为 参考句柄 在最终程序阶段 终止函数 线性程序会执行每一个对象的终止函数finalize()方法 finalize() 成功执行之后Java回收工具将会交付对象 将它所占用的空间由 future 碎片收集功能再生 我没有说 现有 这意味着至少两个碎片收集周期必须被要求用来回收终止对象 听起来这像是有一些消耗的?正确 我们需要一些方法使得空间能够重新利用 (Java新的垃圾回收器需购买支持后才能用) 线性终止函数在系统中没有被给予最大优先权 优先级更高的线程导致终止对象被排列 如果一个线性 终止函数 无法与这个效率保持一致 终止函数队列就会持续增长 导致Java堆不停的被堆积 最终Java堆将会被耗尽 并且java lang OutOfMemoryError将会被抛出 对于任何对象而言 一个Java虚拟机将不会超过一次的引用终止函数finalize()方法 如果finalize()方法抛出了什么例外现象 对象的终止程序就会停止下来 对于类的finalize()方法你几乎可以自由的做任何事情 当你这样做的时候 当对象不再被引用或者不再需要的时候 请不要期望存储 <;空间会被任何一个由Java回收程序回收再生的对象占领 为什么? finalize()方法将要完整的按进度完成的这种情况是不可控的 最坏的情况是 当这里没有更多涉及到对象的时候 也许它甚至不会被解决 这意味着任何具有finalize()方法的对象被回收都是无法被保障的 这是内存 <>管理发展的一个潜在危险 不必多说 有相当大的开销是花费在队列排列 运行finalize()方法以及将对象反射到下一个碎片整理环节上的 如果你想在对象上运行函数 考虑到终止函数作为最后一个方法 执行你自己的清理垃圾方法 这将会更加的平稳 完全信任终止函数来进行事后的垃圾清理工作是非常危险的 特别是当你的终止对象涉及到本地资源的时候 Java 终止函数的实际操作体验 ObjectWYieldFinalizer内 我们可以伴随着线性yield()执行finalize()方法 这样finalize()就不能完全执行 见代码表一 线性yield()方法从正在运行的程序中阻止现有的线性程序执行 以及允许其它的线性程序执行 如果终止函数线性程序调用这种finalize()方法 它将会暂停执行 代码表一 /* * @Author : Jinwoo Hwang * (C) Copyright IBM Corp All Rights Reserved */ public class ObjectWYieldFinalizer { protected void finalize() throws Throwable { Thread yield(); } } public class TestObjectWYieldFinalizer { public static void main(String[] args) { while(true){ ObjectWYieldFinalizer o = new ObjectWYieldFinalizer(); } } lishixinzhi/Article/program/Java/hx/201311/271132023-06-20 19:42:051
java 编程规范里的问题,下面这段话怎么理解呢?为什么要调用super.finalize(),谁能代码示例一下呢?
finalize的作用是释放类的相关资源,比如打开的文件,内存中占用的空间等等如果是子类直接覆盖了父类,那么父类的资源可能得不到有效释放,所以要求调用一次父类的finalize方法之所以放到最后调用,是考虑可能子类的逻辑中还需要实用父类的方法,如果提前释放了,子类的执行可能出错2023-06-20 19:42:141
关于 flush 方法
final—修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为 abstract的,又被声明为final的。将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为final的方法也同样只能使用,不能重载finally—再异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)。finalize—方法名。java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。2023-06-20 19:42:332
Object 对象的方法有哪些?分别有什么作用?该什么场景用?
1.clone方法 保护方法,实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedException异常。 主要是JAVA里除了8种基本类型传参数是值传递,其他的类对象传参数都是引用传递,我们有时候不希望在方法里讲参数改变,这是就需要在类中复写clone方法。 2.getClass方法 final方法,获得运行时类型。 3.toString方法 该方法用得比较多,一般子类都有覆盖。 4.finalize方法 该方法用于释放资源。因为无法确定该方法什么时候被调用,很少使用。 finalize方法在垃圾回收时一定会被执行,而如果在此之前显示执行的话,也就是说finalize会被执行两次以上,而在第一次资源已经被释放,那么在第二次释放资源时系统一定会报错,因此一般finalize方法的访问权限和父类保持一致,为protected。 5.equals方法 该方法是非常重要的一个方法。一般equals和==是不一样的,但是在Object中两者是一样的。子类一般都要重写这个方法。 6.hashCode方法 该方法用于哈希查找,可以减少在查找中使用equals的次数,重写了equals方法一般都要重写hashCode方法。这个方法在一些具有哈希功能的Collection中用到。 一般必须满足obj1.equals(obj2)==true。可以推出obj1.hash- Code()==obj2.hashCode(),但是hashCode相等不一定就满足equals。不过为了提高效率,应该尽量使上面两个条件接近等价。 如果不重写hashcode(),在HashSet中添加两个equals的对象,会将两个对象都加入进去。 7.wait方法 wait方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。wait()方法一直等待,直到获得锁或者被中断。wait(long timeout)设定一个超时间隔,如果在规定时间内没有获得锁就返回。 调用该方法后当前线程进入睡眠状态,直到以下事件发生。 (1)其他线程调用了该对象的notify方法。 (2)其他线程调用了该对象的notifyAll方法。 (3)其他线程调用了interrupt中断该线程。 (4)时间间隔到了。 此时该线程就可以被调度了,如果是被中断的话就抛出一个InterruptedException异常。 8.notify方法 该方法唤醒在该对象上等待的某个线程。 9.notifyAll方法 该方法唤醒在该对象上等待的所有线程。2023-06-20 19:42:401
final, finally, finalize 的区别。
final 最后的,最终的,是形容词,用来修饰Be动词,名词等finally 最后地,最终地,是副词,用来修饰副词,动词finalize 完成,结束,使……完成,是动词2023-06-20 19:43:242
final,finally,finalsize 它们有什么区别啊!
楼上回答的很完整了2023-06-20 19:43:414
finally代码块和finalize()方法有什么区别?
【答案】:无论是否抛出异常,finally代码块都会执行,它主要是用来释放应用占用的资源。finalize()方法是Object类的一个protected方法,它是在对象被垃圾回收之前由Java虚拟机来调用的。2023-06-20 19:43:481
js有 finalize 的吗
没有,javascript是一种弱类型语言,没有finalize。2023-06-20 19:43:551
finalized的意思
finalize英 [u02c8fau026anu0259lau026az] 美 [u02c8fau026anu0259u02cclau026az]vt.完成; 使结束; 使落实vi.定案; 把…最后定下来网络结束; 方法; 定妥第三人称单数: finalizes 现在分词: finalizing过去式: finalized 过去分词: finalized这句话应该少了主语,我就先补个 it 吧。It will be finalized after you are on boardIt will be finalized是主句;after you are on board做时间主语从句。翻译就是:等你上船/上飞机/上火车,它(根据你实际要描述的主语来翻译)就将结束/完成。draft的英语例句1. Officials have now been delegated to start work on a draft settlement.现在已经委派官员着手起草解决方案。2. When the first draft was completed, Nichols typed it up.当初稿完成以后,尼科尔斯将它打印了出来。3. The money was payable by a draft drawn by the home.这笔钱可凭国内承兑的汇票支付。4. Ten days later Carmen received a bank draft for a plane ticket.10天后卡门收到了一张用于购买机票的银行汇票。5. You pay for the car by banker"s draft in the local currency.以本币银行汇票支付车款。6. I"m supposed to have handed in a first draft of my dissertation.我本该把论文的初稿交上去了。2023-06-20 19:44:021
java里 一个对象的finalize()自动被调用的时候 该对象是不是被回收了
finalize()在什么时候被调用?有三种情况1.所有对象被Garbage Collection时自动调用,比如运行System.gc()的时候.2.程序退出时为每个对象调用一次finalize方法。3.显式的调用finalize方法2023-06-20 19:44:252
finalize()方法什么时候被调用?析构函数(finalization)的目的是什么?
【答案】:在释放对象占用的内存之前,垃圾收集器会调用对象的finalize()方法。一般建议在该方法中释放对象持有的资源。2023-06-20 19:44:311
android开发中Final、finally、finanlize()的区别是什么?
【答案】:final用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。finally是异常处理语句结构的一部分,表示总是执行。finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。2023-06-20 19:44:391
Java中使用finalize()方法出现了null
没有问题 你的第一个 new Test() 没有赋name的值2023-06-20 19:44:571
高性能JAVA代码之
更甚者你写的代码,GC根本就回收不了,直接系统挂掉。GC是一段程序,不是智能,他只回收他认为的垃圾,而不是回收你认为的垃圾。GC垃圾回收:Grabage Collection相信学过JAVA的人都知道这个是什么意思.但是他是如何工作的呢?首先,JVM在管理内存的时候对于变量的管理总是分新对象和老对象。新对象也就是开发者new出来的对象,但是由于生命周期短,那么他占用的内存并不是马上释放,而是被标记为老对象,这个时候该对象还是要存在一段时间。然后由JVM决定他是否是垃圾对象,并进行回收。所以我们可以知道,垃圾内存并不是用完了马上就被释放,所以就会产生内存释放不及时的现象,从而降低了内存的使用。而当程序浩大的时候。这种现象更为明显,并且GC的工作也是需要消耗资源的。所以,也就会产生内存浪费。JVM中的对象生命周期里谈内存回收:对象的生命周期一般分为7个阶段:创建阶段,应用阶段,不可视阶段,不可到达阶段,可收集阶段,终结阶段,释放阶段。创建阶段:首先大家看一下,如下两段代码:test1:for( int i=0; i10000; i++)Object obj=new Object();test2:Object obj=null;for( int i=0; i10000; i++)obj=new Object();这两段代码都是相同的功能,但是显然test2的性能要比test1性能要好,内存使用率要高,这是为什么呢?原因很简单,test1每次执行for循环都要创建一个Object的临时对象,但是这些临时对象由于JVM的GC不能马上销毁,所以他们还要存在很长时间,而test2则只是在内存中保存一份对象的引用,而不必创建大量新临时变量,从而降低了内存的使用。另外不要对同一个对象初始化多次。例如:public class A{private Hashtable table = new Hashtable();public A(){ table = new Hashtable();// 这里应该去掉,因为table已经被初始化.}}这样就new了两个Hashtable,但是却只使用了一个。另外一个则没有被引用.而被忽略掉.浪费了内存.并且由于进行了两次new操作.也影响了代码的执行速度。应用阶段:即该对象至少有一个引用在维护他.不可视阶段:即超出该变量的作用域。这里有一个很好的做法,因为JVM在GC的时候并不是马上进行回收,而是要判断对象是否被其他引用在维护.所以,这个时候如果我们在使用完一个对象以后对其obj=null或者obj.doSomething()操作,将其标记为空,可以帮助JVM及时发现这个垃圾对象.不可到达阶段:就是在JVM中找不到对该对象的直接或者间接的引用。可收集阶段,终结阶段,释放阶段:此为回收器发现该对象不可到达,finalize方法已经被执行,或者对象空间已被重用的时候。JAVA的析构方法:可能不会有人相信,JAVA有析构函数? 是的,有。因为JAVA所有类都继承至Object类,而finalize就是Object类的一个方法,这个方法在JAVA中就是类似于C++析构函数.一般来说可以通过重载finalize方法的形式才释放类中对象.如:public class A{public Object a;public A(){ a = new Object ;}protected void finalize() throws java.lang.Throwable{a = null; // 标记为空,释放对象super.finalize(); // 递归调用超类中的finalize方法.}}当然,什么时候该方法被调用是由JVM来决定的一般来说,我们需要创建一个destory的方法来显式的调用该方法.然后在finalize也对该方法进行调用,实现双保险的做法.由于对象的创建是递归式的,也就是先调用超级类的构造,然后依次向下递归调用构造函数,所以应该避免在类的构造函数中初始化变量,这样可以避免不必要的创建对象造成不必要的内存消耗.当然这里也就看出来接口的优势.数组的创建:由于数组需要给定一个长度,所以在不确定数据数量的时候经常会创建过大,或过小的数组的现象.造成不必要的内存浪费,所以可以通过软引用的方式来告诉JVM及时回收该内存.(软引用,具体查资料).例如:Object obj = new char[10000000000000000];SoftReference ref = new SoftReference(obj);共享静态存储空间:我们都知道静态变量在程序运行期间其内存是共享的,因此有时候为了节约内存工件,将一些变量声明为静态变量确实可以起到节约内存空间的作用.但是由于静态变量生命周期很长,不易被系统回收,所以使用静态变量要合理,不能盲目的使用.以免适得其反。因此建议在下面情况下使用:1,变量所包含的对象体积较大,占用内存过多.2,变量所包含对象生命周期较长.3,变量所包含数据稳定.4,该类的对象实例有对该变量所包含的对象的共享需求.(也就是说是否需要作为全局变量).对象重用与GC:有的时候,如数据库操作对象,一般情况下我们都需要在各个不同模块间使用,所以这样的对象需要进行重用以提高性能.也有效的避免了反复创建对象引起的性能下降.一般来说对象池是一个不错的注意.如下:public abstarct class ObjectPool{private Hashtable locked,unlocked;private long expirationTime;abstract Object create();abstract void expire( Object o);abstract void validate( Object o);synchronized Object getObject(){...};synchronized void freeObject(Object o){...};}这样我们就完成了一个对象池,我们可以将通过对应的方法来存取删除所需对象.来维护这快内存提高内存重用.当然也可以通过调用System.gc()强制系统进行垃圾回收操作.当然这样的代价是需要消耗一些cpu资源.不要提前创建对象:尽量在需要的时候创建对象,重复的分配,构造对象可能会因为垃圾回收做额外的工作降低性能.JVM内存参数调优:强制内存回收对于系统自动的内存回收机制会产生负面影响,会加大系统自动回收的处理时间,所以应该尽量避免显式使用System.gc(),JVM的设置可以提高系统的性能.例如:java -XX:NewSize=128m -XX:MaxNewSize=128m -XX:SurvivorRatio=8 -Xms512m -Xmx512m具体可以查看java帮助文档.我们主要介绍程序设计方面的性能提高.JAVA程序设计中有关内存管理的其他经验:根据JVM内存管理的工作原理,可以通过一些技巧和方式让JVM做GC处理时更加有效.,从而提高内存使用和缩短GC的执行时间.1,尽早释放无用对象的引用.即在不使用对象的引用后设置为空,可以加速GC的工作.(当然如果是返回值.....)2,尽量少用finalize函数,此函数是JAVA给程序员提供的一个释放对象或资源的机会,但是却会加大GC工作量.3,如果需要使用到图片,可以使用soft应用类型,它可以尽可能将图片读入内存而不引起OutOfMemory.4,注意集合数据类型的数据结构,往往数据结构越复杂,GC工作量更大,处理更复杂.5,尽量避免在默认构造器(构造函数)中创建,初始化大量的对象.6,尽量避免强制系统做垃圾回收.会增加系统做垃圾回收的最终时间降低性能.7,尽量避免显式申请数组,如果不得不申请数组的话,要尽量准确估算数组大小.8,如果在做远程方法调用.要尽量减少传递的对象大小.或者使用瞬间值避免不必要数据的传递.9,尽量在合适的情况下使用对象池来提高系统性能减少内存开销,当然,对象池不能过于庞大,会适得其反.2023-06-20 19:45:041
重分悬赏JAVA面试问题
呵呵``2023-06-20 19:45:136
finalizing是什么意思
finalizing adj. 最後的Negotiators from the three countries finalized the agreement in August.3个国家的谈判代表在8月最终确定了协议。2023-06-20 19:45:262
[ A] conceming[ B] following[ C] finalizing[ D] ensuring
【答案】:B31.B【精析】本题考查上下文的语义衔接。concem涉及,与…有关系;follow接着…来到或发生;finalize最后确定下来;ensure保证。根据上下文,这里指的应该是获得学士学位后再获得法律、医学等专业学位,故选B。2023-06-20 19:45:341
深入理解GC垃圾回收机制
在我们程序运行中会不断创建新的对象,这些对象会存储在内存中,如果没有一套机制来回收这些内存,那么被占用的内存会越来越多,可用内存会越来越少,直至内存被消耗完。于是就有了一套垃圾回收机制来做这件维持系统平衡的任务。 1.确保被引用对象的内存不被错误的回收 2.回收不再被引用的对象的内存空间 给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时, 计数器值就减1;任何时刻计数器为0的对象就是不可能再被使用的。 优点:引用计数收集器可以很快地执行,交织在程序的运行之中。 缺点:很难处理循环引用,比如上图中相互引用的两个对象,计数器不为0,则无法释放,但是这样的对象存在是没有意义的,空占内存了。 引用计数法处理不了的相互引用的问题,那么就有了可达性分析来解决了这个问题。 从GC Roots作为起点,向下搜索它们引用的对象,可以生成一棵引用树,树的节点视为可达对象,反之最终不能与GC Roots有引用关系的视为不可达,不可达对象即为垃圾回收对象。 我自己的理解是,皇室家族每过一段时间,会进行皇室成员排查,从皇室第一代开始往下找血缘关系的后代,如果你跟第一代皇室没有关系,那么你就会被剔除皇室家族。 1.虚拟机栈中引用的对象(正在运行的方法使用到的变量、参数等) 2.方法区中类静态属性引用的对象(static关键字声明的字段) 3.方法区中常量引用的对象,(也就是final关键字声明的字段) 4.本地方法栈中引用的对象(native方法) 1.显示地赋予某个对象为null,切断可达性 在main方法中创建objectA、objectB两个局部变量,而且相互引用。相互引用直接调System.gc()是回收不了的。而将两者都置为null,切断相互引用,切断了可达性,与GCRoots无引用,那么这两个对象就会被回收调。 2.将对象的引用指向另一个对象 这里将one的引用也指向了two引用指向的对象,那么one原本指向的对象就失去了GCRoots引用,这里就判断该对象可被回收。 3.局部对象的使用 当方法执行完,局部变量object对象会被判定为可回收对象。 4.只有软、弱、虚引用与之关联 new出来的对象被强引用了,就需要去掉强引用,改为弱引用。被弱引用之后,需要置空来干掉强引用,达到随时可回收的效果。 只被软引用的对象在内存不足的情况,可能会被GC回收掉。 只被弱引用持有的对象,随时都可能被GC回收,该对象就为可回收对象。 是不是被判定为了可回收对象,就一定会被回收了呢。其实Ojbect类中还有一个finalize方法。这个方法是对象在被GC回收之前会被触发的方法。 该方法翻译过来就是:当垃圾回收确定不再有对该对象的引用时,由垃圾回收器在对象上调用。子类重写finalize方法以处置系统资源或执行其他清除。说人话就是对象死前会给你一个回光返照,让你清醒一下,想干什么就干什么,甚至可以把自己救活。我们可以通过重写finalize方法,来让对象复活一下。 示例: 执行的结果: 这里我们重写FinalizeGC类的finalize方法, 使用FinalizeGC.instance = this语句,让对象又有了引用,不再被判定为可回收对象,这里就活了。然后再置空再回收一下,这个对象就死了,没有再被救活了。所以finalize方法只能被执行一次,没有再次被救活的机会。 在JDK1.8版本废弃了永久代,替代的是元空间(MetaSpace),元空间与永久代上类似,都是方法区的实现,他们最大区别是:元空间并不在JVM中,而是使用本地内存。 元空间有注意有两个参数: MetaspaceSize :初始化元空间大小,控制发生GC阈值 MaxMetaspaceSize : 限制元空间大小上限,防止异常占用过多物理内存 为什么移除永久代? 移除永久代原因:为融合HotSpot JVM与JRockit VM(新JVM技术)而做出的改变,因为JRockit没有永久代。 有了元空间就不再会出现永久代OOM问题了! 1.Generational Collection(分代收集)算法 分代收集算法是GC垃圾回收算法的总纲领。现在主流的Java虚拟机的垃圾收集器都采用分代收集算法。Java 堆区基于分代的概念,分为新生代(Young Generation)和老年代(Tenured Generation),其中新生代再细分为Eden空间、From Survivor空间和To Survivor空间。 (Survivor:幸存者) 分代收集算法会结合不同的收集算法来处理不同的空间,因此在学习分代收集算法之前我们首先要了解Java堆区的空间划分。Java堆区的空间划分在Java虚拟机中,各种对象的生命周期会有着较大的差别。因此,应该对不同生命周期的对象采取不同的收集策略,根据生命周期长短将它们分别放到不同的区域,并在不同的区域采用不同的收集算法,这就是分代的概念。 当执行一次GC Collection时,Eden空间的存活对象会被复制到To Survivor空间,并且之前经过一次GC Collection并在From Survivor空间存活的仍年轻的对象也会复制到To Survivor空间。 对象进入到From和To区之后,对象的GC分代年龄ege的属性,每经过GC回收存活下来,ege就会+1,当ege达到15了,对象就会晋级到老年代。 2.Mark-Sweep(标记-清除)算法 标记清除:标记阶段的任务是标记出所有需要被回收的对象,清除阶段就是回收被标记的对象所占用的空间。标记-清除算法主要是运用在Eden区,该区对象很容易被回收掉,回收率很高。 3.Copying(复制)算法 复制算法的使用在From区和To区,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用的内存空间一次清理掉,这样一来就不容易出现内存碎片的问题。 缺点:可使用内存缩减为一半大小。 那么复制算法使可使用内存大小会减半,设计上是怎么解决这个问题的呢。就是给From和To区划分尽可能小的区域。经过大数据统计之后,对象在第一次使用过后,绝大多数都会被回收,所以能进入第一次复制算法的对象只占10%。那么设计上,Eden、From、To区的比例是8:1:1,绝大多数对象会分配到Eden区,这样就解决了复制算法缩减可用内存带来的问题。 4.Mark-Compact (标记—整理)算法 在新生代中可以使用复制算法,但是在老年代就不能选择复制算法了,因为老年代的对象存活率会较高,这样会有较多的复制操作,导致效率变低。标记—清除算法可以应用在老年代中,但是它效率不高,在内存回收后容易产生大量内存碎片。因此就出现了一种标记—整理算法,与标记—清除算法不同的是,在标记可回收的对象后将所有存活的对象压缩到内存的一端,使它们紧凑地排列在一起,然后对边界以外的内存进行回收,回收后,已用和未用的内存都各自一边。 垃圾收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现: Serial 收集器(复制算法): 新生代单线程收集器,标记和清理都是单线程, 优点是简单高效; Serial Old 收集器 (标记-整理算法): 老年代单线程收集器,Serial 收集器 的老年代版本; ParNew 收集器 (复制算法): 新生代收并行集器,实际上是 Serial 收集器 的多线程版本,在多核 CPU 环境下有着比 Serial 更好的表现; CMS(Concurrent Mark Sweep)收集器(标记-清除算法): 老年代并行 收集器,以获取最短回收停顿时间为目标的收集器,具有高并发、低停顿 的特点,追求最短 GC 回收停顿时间。2023-06-20 19:45:411
对象死了怎么办?
在Java虚拟机中,堆里面存放着Java世界中几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事情就是确定这些对象之中那些还“存活”着,哪些已经“死去”(死去就是不可能再被任何途径使用的对象)了。 那么对象销毁过程。也就是finalization机制。 这是对象销毁前的一个回调方法:finalize() 它是Object类中的一个方法,在对象被最终回收之前调用一次(只调用一次)。 Java语言是提供了对象终止(finalization)机制来允许开发人员提供对象被销毁之前的自定义处理逻辑。 就是Java是允许对象在销毁之前去调用finalize()方法,去调用一些逻辑。(但是一般建议是不使用的) 当垃圾回收器发现没有引用一个对象,即:垃圾回收此对象之前,总会先调用这个对象的finalize()方法,但是一个对象的finalize()方法只被调用一次。 finalize() 方法允许在子类中被重写,用于在对象被回收时进行资源释放。通常在这个方法中进行一些资源的释放和清理工作。 比如:关闭文件、套接字和数据库连接等。 在父类Object类中的finalize()源码: 就是空的,具体实现什么,就是要在子类重写,写入需要的操作。 但是在实际操作中,永远都不要显示调用某个对象的finalize()方法,应该交给垃圾回收机制调用。 在里面写代码一定要慎重 主要有以下原因: 这样做的原因是,如果某个对象的finalize()方法执行缓慢,或者更极端的死循环,将会导致F-Queue队列中的其他对象永久处于等待,甚至导致整个内存回收子系统的奔溃。(F-Queue队列具体是什么,看下面) 上面提到自己写的finalize()方法会造成对象的复活,那么在这就主要讨论一些对象的生存还是死亡。 这里所说的对象问题都是在垃圾标记阶段算法 可达性在算法中表现。 因为在堆当中产生一个垃圾就回收一个垃圾的这种做法,显然是不合理的,所以在内存当中,是产生一个垃圾,先进行标记,当内存满的时候,再将标记的对象进行回收操作。 所以在标记阶段,在虚拟机中因为finalize()方法的存在,虚拟机中的对象又分为三种可能的状态 在以上3种状态中,是由于finalize()方法的存在,进行的区分,只有在对象到达不可触及时才可以被回收。 即使在垃圾标记阶段算法中可达性算法中的被判定为不可达的对象,但也不是要“非死不可”的,在这个时候它们暂时还处于“缓刑”阶段,要真正的宣告一个对象死亡,最多是要经历两次标记过程的: (在这个之间就会出现一个问题,这个方法的执行时间,完全是由线程决定的,恰好在开始执行finalize()的时候,在执行“复活”的时候线程结束了,那也就复活失败了) 代码演示: 从代码中运行结果可以明显地看出,demo的对象finalize()方法确实是可以被垃圾收集器触发的,并且在被收集前成功可以逃脱的。 在这个代码中也完整地体现出来,虽然运行了同样的代码,但是执行结果是一次成功一次失败,这也说明出来finalize方法是只能被调用一次的,如果再在下一次回收的时候,它的finalize方法是不会在被调用的。 最后再次说明一下,虽然Java拥有这样的机制,但是是完全不建议使用的,它的运行代价高,不确定性大,无法保证各个对象的调用顺序,在官方说明中都明确说明了不建议使用的。最开始做这个完全是为了使传统的C、C++程序员更容易接受Java所做的一种妥协。 而我们要做“关闭外部资源”之类的清理工作的时候,完全是可以采用try-finally等方式来使用的。 我是一个做Java开发的不太正经的程序员,最近金三银四跳槽的人很多,给大伙发点福利吧,之前自己和朋友整理的一些Java成长知识点和面经、面试题。如果有最近打算跳槽,或者想成长的技术人都可以看一看,应该会有比较大的帮助。 文中不能发链接,私信我发送“ 666 ”免费领取。2023-06-20 19:45:471
可达性分析算法
可达性分析算法通过一系列成为GCRoots的对象作为起始点,从这些节点上向下搜索,所走过的路径称为引用链,当一个对象没有任何引用链与GCRoots连接时就说明此对象不可用,也就是对象不可达 GCRoots对象 1、虚拟机栈中引用对象(栈帧中本地变量表) 2、方法中类的静态属性引用对象 3、方法区中常量引用对象 4、native方法引用的对象 可达性分析算法整个清理流程 1、第一次标记:对象经过可达性分析,没有GCRoots引用链,则进行第一次标记筛选,筛选条件是:该对象是否必要执行finalize()方法:没有覆盖finalize方法或该方法已经执行过。如果有必要执行,则该对象放在F-Queue队列,并稍后在由虚拟 机建立的低优先级 Finalizer 线程中触发该对象的 finalize()方法,但不保证一定等 待它执行结束。 2、第二次标记:GC 对 F-Queue 队列里的对象进行第二次标记,如果在第二次标记 时该对象又成功被引用,则会被移除即将回收的集合,否则会被回收 注意:任何一个对象finalize方法只会被系统调用一次2023-06-20 19:45:551
VB代码解释一下
DFSF2023-06-20 19:46:034
JVM垃圾收集机制
所谓jvm垃圾回收机制其实就是相较于于c、c++语言的优势之一是自带垃圾回收器,垃圾回收是指不定时去堆内存中清理不可达对象。垃圾收集器在一个Java程序中的执行是自动的,不能强制执行,程序员唯一能做的就是通过调用System.gc 方法来建议执行垃圾收集器。2023-06-20 19:46:222
java 中System.runFinalization什么意思?
调用System.runFinalization()表示java虚拟机会做一些努力运行已被丢弃对象(即没有被任何对象引用的对象)的finalize方法,前提是这些被丢弃对象的finalize方法还没有被调用过。2023-06-20 19:46:311
java对象资源无法释放属于
系统给的内存少,没有达到释放的地步。在 Java 中,当你创建一个对象时,Java 虚拟机JVM为该对象分配内存,调用构造函数并开始跟踪你使用的对象,当你停止使用一个对象就是说,当没有对该对象有效的引用时,JVM 通过垃圾回收器将该对象标记为释放状态。当垃圾回收器将要释放一个对象的内存时,它调用该对象的finalize方法如果该对象定义了此方法,垃圾回收器以独立的低优先级的方式运行,只有当其他线程挂起等待该内存释放的情况出现时,它才开始运行释放对象的内存,事实上,你可以调用System.gc方法强制垃圾回收器来释放这些对象的内存,在以上的描述中,有一些重要的事情需要注意。首先,只有当垃圾回收器释放该对象的内存时,才会执行finalize,如果在 Applet 或应用程序退出之前垃圾回收器没有释放内存,垃圾回收器将不会调用finalize。其次,除非垃圾回收器认为你的 Applet 或应用程序需要额外的内存,否则它不会试图释放不再使用的对象的内存,换句话说,这是完全可能的,一个 Applet 给少量的对象分配内存,没有造成严重的内存需求,于是垃圾回收器没有释放这些对象的内存就退出了。2023-06-20 19:46:381
final的派生词是什么?
finally副词finalize动词finalization名词2023-06-20 19:46:462