Ani*_*kur 2 java garbage-collection jvm finalizer
至于我的理解是finalize()和GC是两个不同的方面.GC使用finalize()方法释放对象内存.我们无法说明何时会发生GC(即使我们明确地调用System.gc()).但是我们可以在Object上显式调用finalize().
Will the function be executed immediately(memory freed) or it waits till GC
occurs like System.gc() call?
Run Code Online (Sandbox Code Playgroud)
此外,根据文档,对于任何给定对象,Java虚拟机永远不会多次调用finalize方法.
那么当我们先调用finalize()并在稍后的时间调用GC时会发生什么.
If object memory is not freed on explicit call to object.finalize() then would't
it being called again in the GC process violate the calling only once rule?
Run Code Online (Sandbox Code Playgroud)
你完全错了.
简短回答:
finalize()是在对象准备好进行垃圾收集之前清理资源(例如打开文件)的一种方法(当没有对象具有强引用时).它可能/不会被调用.它比内存释放领先一步.
答案很长:
有一个单独的守护程序线程称为终结器线程,它负责调用finalize()方法.终结队列是一个队列,其中放置了准备被称为finalize()方法的对象.
当一个对象准备好进行垃圾收集时,垃圾收集器线程会检查这个特定对象是否有来自(1)中提到的表的finalize().
2a)如果没有,那么它被发送用于垃圾收集.
2b)它有,然后它被添加到终结队列.并从表(1)中删除对象的条目.
终结器线程继续轮询队列.对于队列中的每个对象,都会调用其finalize()方法.从(2)调用finalize()循环后再次重复.如果此对象仍然没有强引用,则发送给GC.如果有,则调用ALWAYS(2a),因为在(2b)中删除了条目
Basically finalize() method is only called once.
Run Code Online (Sandbox Code Playgroud)
那么上述周期的问题是什么?
从(1).它在对象创建中花费了额外的时间.Java中的内存分配比malloc/calloc等快5到10倍.在注意到表中的对象的过程中,所有获得的时间都丢失了.我曾经尝试过.在循环中创建100000个对象并测量程序在2种情况下终止所花费的时间:一个没有finalize(),第二个是finalize().发现它快了20%.
从(2b):记忆泄漏和饥饿.如果队列中的对象引用了大量内存资源,那么除非该对象已准备好用于GC,否则所有这些对象都不会被释放.如果所有对象都是重量级对象,那么可能会出现短缺.
From(2b):因为finalize()只调用一次,如果在finalize()中你有一个对"this"对象的强引用.下次永远不会调用对象的finalie(),因此可能会使对象处于不一致状态.
如果在finalize()内部抛出异常,则忽略它.
您不知道何时调用finalize(),因为您无法控制何时调用GC.有时候你可能会在finalize()中打印值,但输出永远不会显示,因为你的程序可能在调用finalize()时被终止.
因此避免使用它.而是创建一个方法,例如dispose(),它将关闭必需资源或最终日志等.
| 归档时间: |
|
| 查看次数: |
3479 次 |
| 最近记录: |