Java本地资源映射的有效性(以及如何保持它们同步) [英] LIfecycle of mapping of native resources in Java (and how to keep them in sync)

查看:297
本文介绍了Java本地资源映射的有效性(以及如何保持它们同步)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑这种情况:

Java和一些(昂贵的)本地资源之间存在连接,这是要映射到Java的要求。问题是关于资源的生命周期以及如何在native和java上使用这些资源,只要它们是需要的。假设我们可以根据需要使用两种方式来激活JNI连接。



规则如下:


  • 只要包装器Java对象需要它们,资源就会保持活动状态。如果需要,可以对Java对象进行垃圾回收。

  • 只要本地部分需要,资源就会保持活动状态。 / b>
  • 如果Java对象已被GC化,应该存在一种重新生成Java对象的机制。这个Java包装器对象可能具有字段,而不是映射到本地资源,这些字段需要出现在转化对象中。

  • 有一种机制可以通知本地作为客户端的Java不再需要资源(不保证将来不会再请求它),并且通知Java本地已经决定没有其他客户端需要这些资源了。


    可能的解决方案列表(以及它们为什么不起作用):




    • 保留一个WeakReference包装器的Map:可能的java字段将会出现问题,这些字段将被GC化并且无法重新创建


    • 使用finalize和回收数据:这是不可能的,因为GC最多只能调用一次。


    • 使用 .clone():它可能会被覆盖,并且可能数据很宽松


    • 使用反射收集所有私人领域,并重新申请新创建的Jav一个对象:构造函数是未知的(可能会产生各种副作用)

    • ...?




    以下是原始(错误)问题。任何想法如何保证这些资源和Java之间的连接?解决方案

),其中每个资源的所有者负责在不需要时释放该资源。你似乎在描述一个系统,其中原生资源的所有权被掩盖 - 这是你需要解决的问题。



这听起来像你需要某种资源管理器,它本身可能需要Java和本地组件。这:



  • 有一种机制可以通知本地部分,Java作为客户端不会再也不需要资源(不能保证
    将来不会再请求它),并且通知Java
    本地已经决定没有其他客户想要资源任何


让我觉得您可能已经拥有一部分,但您的设计似乎竭尽全力让事情变得艰难。特别是,这个:



  • 如果已经存在一个机制来重塑Java对象GC'ed。这个Java包装器对象可能有字段,而不是
    映射到本地资源,这些资源需要出现在
    转生对象中。


< blockquote>

或多或少意味着不,实际上你不能允许那些Java端对象被GC化。你需要在Java方面保持它们的状态,或者至少它的一个重要部分。资源管理器需要跟踪它,并且只要你的策略要求就阻止它被GC'd。



以下是设计类似的一种方法:在Java方面,资源管理器维护本地资源和Java方面属性之间的关联。可能存在某种基本的数据对象,为此,在客户端使用的包装器和基础原生资源之间。 根据要求,资源管理器手Java客户端访问本地资源和相关Java数据的主要Java包装对象的实例。

  • 资源管理器有一个机制来找出什么时候那些主要的Java端对象不再需要。这可以通过 ReferenceQueue - do not 依赖终结器 - 但我建议将它们设置为 Closeable code>,并让他们的用户负责在完成它们时关闭它们。

  • Java和本地资源管理器配合根据您选择的任何政策确定何时发布本地资源。最简单的方法就是在任何一方不再有任何客户的情况下发布它们,但是您需要确定它是否与重新生成包装对象的能力一致。




  • 听起来您需要在Java和本地方之间拥有比您迄今为止所描述的更丰富的消息集,或者您已经拥有的消息至少需要额外的语义。例如,您可能需要说至少有一个客户端在这边。此外,您可能需要消息来协商删除资源,或者至少返回现有消息的值,以指示是否应删除资源。



    另外,请注意使所有这些线程安全。即使你规定客户端负责以线程安全的方式使用单独的包装器,但如果资源管理器组件不是线程安全的,你不会仅仅是要求,但实际上要求很麻烦。 / p>

    Please consider this scenario:

    There is a connection between Java and some (expensive) native resources, which is a requirement to be mapped to Java. The question is about the lifecycle of the resources and how these will be available on both native and java, as long as they are needed. Let's assume that we can have an active JNI connection both ways, as required.

    The rules are as follows:

    • The resources will stay live as long as the wrapper Java object needs them. The Java object could be garbage collected if desired.

    • The resources will stay live as long as the native part needs them.

    • There should exist a mechanism to "reincarnate" the Java object if it has been GC'ed. This Java wrapper object might have fields, not mapped to the native resources, which need to appear in the reincarnated object.

    • There is a mechanism to inform the native part that Java, as a client, doesn't need the resource any more (with no guarantee that it will not request it again in the future) as well as to inform Java that native has decided that no other clients want the resources any more.

    Possible list of solutions (and why they won't work):

    • Keep a Map of WeakReference of wrappers: there will be a problem with the possible java fields which will be GC'ed and unable to recreate

    • Using "finalize" and recycle data: it is not possible since it is called at most once by GC.

    • Using .clone() : It could be overriden and possibly loose data

    • Use Reflection to gather all private fields and reapply on the newly create Java object: the constructor is unknown (and may produce various side effects)

    • ... ?

    Here is the original (wrong) question. Any ideas how to secure the connection between these resources and Java?

    解决方案

    Managing resources properly requires maintaining a sense of ownership (possibly transferable), where the owner of each resource is responsible for releasing that resource when it becomes unneeded. You seem to be describing a system where ownership of the native resources is obscured -- this is the problem you need to solve.

    It sounds like you need to some kind of resource manager, which may itself need both Java and native components. This:

    • There is a mechanism to inform the native part that Java, as a client, doesn't need the resource any more (with no guarantee that it will not request it again in the future) as well as to inform Java that native has decided that no other clients want the resources any more.

    makes me think that you may already have part of one, but your design seems to go out of the way to make things hard. In particular, this:

    • There should exist a mechanism to "reincarnate" the Java object if it has been GC'ed. This Java wrapper object might have fields, not mapped to the native resources, which need to appear in the reincarnated object.

    more or less means that no, in fact you can't allow those Java-side objects to be GC'd. You need to maintain their state, or at least an essential part of it, on the Java side. The resource manager needs to track that, and prevent it from being GC'd as long as your policy demands that.

    Here's one approach to designing something like that:

    • On the Java side, the resource manager maintains an association between native resources and Java-side properties. Possibly there is some kind of essential data object that for that, between the wrappers used by clients and the underlying native resource.

    • As requested, the resource manager hands out instances of the main Java-side wrapper objects by which clients access the native resources and associated Java data.

    • The resource manager has a mechanism to find out when those main Java-side objects are no longer needed. That could be via a ReferenceQueue -- do not rely on finalizers -- but I recommend instead making them Closeable, and making their users responsible for closing them when they are done with them.

    • The Java and the native sides of the resource manager cooperate to determine when to release the native resources, based on whatever policy you choose. Simplest would be to release them when there are no longer any clients on either side, but you'll need to decide whether that's consistent with the ability to "reincarnate" wrapper objects.

    It does sound like you need a richer set of messages between the Java and native sides than you've described so far, or at least additional semantics for the messages you already have. For example, you may need messages that say "there is at least one client on this side again". Also you may need messages to negotiate for resource removal, or at least return values for your existing messages to indicate whether resource removal should take place.

    Also, do take care to make all this thread-safe. Even if you stipulate that clients are responsible for using individual wrappers in a thread-safe manner, you would not merely be asking for, but practically demanding trouble if the resource manager components were not thread-safe.

    这篇关于Java本地资源映射的有效性(以及如何保持它们同步)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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