是否有可能使GC管理本地对象的生命周期? [英] Is it possible to make GC manage native object's lifetime?

查看:160
本文介绍了是否有可能使GC管理本地对象的生命周期?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用C ++和C#经验和一些小Java知识,我现在开始一个Java + JNI(C ++)项目(Android,如果这很重要的话)。

我有一个本地方法,它创建一些C ++类并将它作为一个Java long值(比如句柄)返回一个指针。然后从这里和那里的Java代码中调用的其他本​​地方法使用该句柄作为参数对此类执行一些本机操作。 C ++方面不拥有这个对象,它是Java方面的。但在当前的架构设计中,很难定义谁确切拥有对象以及何时删除对象。因此,使Java虚拟机垃圾收集器以某种方式管理对象的生命周期可能会很好。 C ++类不消耗任何资源,除了某些内存外,并不大。所以没关系,如果有几个这样的对象不会被破坏。

在C#中,我可能会将本机IntPtr句柄包装在某些托管包装类中。并且在托管包装器被垃圾收集时重写它的终结器来调用本地对象的析构函数。 SafeHandle,AddMemoryPressure等也可能对此有所帮助。

这是Java定稿的另一个故事。你在Java中的'Hello world'之后知道的第二件事是使用finalize是不好的。有没有其他方法可以在Java中实现这一点?也许使用PhantomReference?

解决方案

那么让我们考虑一下为什么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)

这篇关于是否有可能使GC管理本地对象的生命周期?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆