且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

是否有可能使GC管理本地对象的生命周期?

更新时间:2023-01-25 17:55:18

那么让我们考虑一下为什么finalize和co有问题:如你所知,不能保证finalize将在虚拟机关闭之前调用,这意味着特殊的清理代码不一定会运行(这是一个糟糕的决定,我没有发现任何问题需要在清理过程中运行完成队列,但是事情就是这样) 。在C#中,情况也完全相同



现在你的对象只消耗内存,当VM被销毁时,操作系统会清理这些内存,所以唯一的情况是敲定问题对你来说无关紧要。所以是的,你确实可以使用这个变体,它可以很好地工作,但它可能并不被认为是一个很好的体系结构设计 - 只要你的操作系统没有正确处理清理的C ++代码中添加资源,会遇到问题



另外请注意,实现一个终结器会导致GC的额外开销,并且意味着需要两个周期来清除其中一个对象(以及您所做的任何事情,永远不要在finalize方法中保存一个对象)


With C++ and C# experience and some little Java knowledge I'm now starting a Java+JNI (C++) project (Android, if that matters).

I have a native method, that creates some C++ class and returns a pointer to it as a Java long value (say, handle). And then other native methods called from Java code here and there, use the handle as a parameter to do some native operations on this class. C++ side does not own the object, it's Java side who does. But in the current architecture design it's hard to define who exactly owns the object and when to delete it. So it would probably be nice to make Java VM garbage collector to manage the object's lifetime somehow. The C++ class does not consume any resources, except some piece of memory, not large. So it's OK, if several such objects will not be destructed.

In C# I would probably wrap the native IntPtr handle in some managed wrapper class. And override it's finalizer to call native object's destructor when the managed wrapper is garbage collected. SafeHandle, AddMemoryPressure, etc. might be also of help here.

This is a different story with Java's finalize. The second thing you know after 'Hello world' in Java, is that using finalize is bad. Are there any other ways to accomplish this in Java? Maybe using PhantomReference?

Well let's consider the reason WHY finalize and Co are problematic: As you know there's no guarantee that the finalize will be called before the VM is shut down, which means that special cleanup code won't necessarily run (imo a bad decision, I don't see any problems to run through the finalize queue at cleanup, but well that's how it is). Also this is exactly the same situation in C#

Now your objects only consume memory, which will be cleaned up by the OS anyhow when the VM is destroyed, so the only case where finalize is problematic won't matter for you. So yes you can indeed use this variant and it'll work perfectly fine, but it may not exactly be considered a great architectural design - and as soon as you add resources to your C++ code where the OS doesn't handle the cleanup correctly you will run into problems

Also note that implementing a finalizer results in some additional overhead for the GC and means it takes two cycles to cleanup one of these objects (and whatever you do, don't ever save an object in the finalize method)