有没有办法判断Java中的对象是否是软可达的?

发布于 2024-07-21 07:37:04 字数 983 浏览 4 评论 0原文

为了执行一些测试,我想检查当我存储在 SoftReference 对象缓存中的部分或全部对象被释放时,我的应用程序的行为如何。

为了做到这一点,我想手动清除存储在缓存的 SoftReference 对象中的引用 - 模拟虚拟机处理这些对象 - 但前提是当前没有其他任何东西对该对象具有强引用(如果是,则可能是这种情况)另一个进程最近从缓存中检索了引用的对象)。

我的应用程序是单线程的,因此我不需要担心在执行此代码时缓存对象的软可达性发生变化。 这也意味着我目前没有任何锁定机制 - 如果我有的话,我可能会使用它们来确定对象是否“正在使用”,从而强烈可达,但可惜我不需要这种锁定。

我尝试过的一种方法是为存储在缓存中的每个对象创建一个额外的 SoftReference,该对象是通过 ReferenceQueue 注册的。 我希望这样做时,缓存中所有可软访问的对象都会将其附加的 SoftReference 添加到队列中,因此我所要做的就是循环队列,并从缓存中删除这些对象。 然而,GC 似乎会在闲暇时将可软访问的对象排队到各自的队列中,因此不能保证在我完成对缓存中的对象的迭代后,任何内容都会添加到队列中。

我还研究过的一件事是 -XX:SoftRefLRUPolicyMSPerMB JVM 选项,其值非常小。 通过明智的内存分配,这很可能会在软可访问的对象被软访问时从缓存中清除它们,但我真的希望应用程序正常运行,直到我收到从缓存中清除软可访问对象的请求。 作为 JVM 选项,我不相信我可以在应用程序运行时更改此值。

那么,有谁知道如何确定一个对象是否只能软可达(因此可以被清除)?

编辑:一些可能不清楚的额外要点:

  • 当我想要清除这些软引用对象时,应用程序可能会做有用​​的工作。 所以我不想尝试让 GC 为我清除对象。
  • 如果我可以选择清除哪些可轻松到达的对象,那就更好了。
  • 我希望应用程序正常运行,即使用生产内存设置。 更改代码中的设置,然后可以将其重置回其生产值,这很好。

In order to perform some testing, I'd like to check how my application behaves when some or all of the objects I have stored in a cache of SoftReference'd objects are disposed of.

In order to do this, I'd like to manually clear the references stored in the cached SoftReference objects - simulating the VM disposing of those objects - but only if nothing else currently has a strong reference to that object (which could be the case if another process had recently retrieved the referenced object from the cache).

My application is single-threaded, so I don't need to worry about the soft reachability of a cached object changing as this code is executing. This also means that I don't currently have any locking mechanisms - if I did have, I could possibly have used these to determine whether or not an object was 'being used' and hence strongly reachable, but alas I don't have need of such locking.

One approach I have tried is to create an additional SoftReference to every object stored in the cache which is registered with a ReferenceQueue. My hope was that in doing so, all of the softly reachable objects in the cache would have their additional SoftReference added to the queue, so all I had to do was loop over the queue, and remove those objects from my cache. However, it seems that the GC enqueues softly reachable objects to their respective queues at its leisure, so it is not guaranteed that anything will be added to the queue once I've finished iterating through the objects in the cache.

One thing that I have also looked at is the -XX:SoftRefLRUPolicyMSPerMB JVM option with a very small value. With judicious memory allocation, this will quite probably clear softly reachable objects from the cache for me the moment they are softly reachable, but I'd really like the app to run normally until I receive a request to clear the softly reachable objects from the cache. As a JVM option, I don't believe I can alter this value while my app is running.

So, does anyone have any ideas as to how I can determine whether or not an object is only softly reachable (and hence can be cleared)?

Edit: The a few extra points that may not have been clear:

  • The app will probably be doing useful work at the times that I want to clear these softly reference objects out. So I'd prefer to not try and cause the GC to clear objects out for me.
  • It would be preferable if I could select which softly reachable objects were cleared out.
  • I would like to app to run normally, i.e. using production memory settings. Changing settings in code, which can then be reset back to their production values, is fine.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

凤舞天涯 2024-07-28 07:37:04

IIRC,在抛出 OutOfMemoryError 之前(在某种意义上)保证软引用被清除。 因此,如果您分配了大量内存,并且对象没有被强引用,那么它们应该被清除。 (未经测试。)

IIRC, soft references are guaranteed (in some sense) to be cleared before an OutOfMemoryError is thrown. So, if you allocate lots of memory they should get cleared if the objects is not strongly referenced. (Not tested.)

兔姬 2024-07-28 07:37:04

混合一些答案:正如 Tom Hawtin 所说,分配内存直到内存耗尽,例如使用以下代码:

private void doOutOfMemory() {
    try {
        List<byte[]> list = new ArrayList<byte[]>();
        while (true) {
            list.add(new byte[200 * 1024 * 1024]);
        }
    } catch (OutOfMemoryError ex) {
    }
}

如果您不想控制清除哪些对象,请对要保留的对象进行强引用。

您也可以使用weakReferences来代替,并且只调用System.gc()来清除,但不能保证它们总是会被清除......

Mixing some answers: as Tom Hawtin said allocate memory till you go outOfMemory, for example with this code:

private void doOutOfMemory() {
    try {
        List<byte[]> list = new ArrayList<byte[]>();
        while (true) {
            list.add(new byte[200 * 1024 * 1024]);
        }
    } catch (OutOfMemoryError ex) {
    }
}

If you wan't to control what objects are cleared, take a strong reference on the objects you want to keep.

You may also use weakReferences instead and only call System.gc() to clear there is no guarantee they will always be cleared...

兮颜 2024-07-28 07:37:04

测试时用弱参考系统替换当前的软参考系统。

一旦发生这种情况,弱引用系统就会删除没有其他传入引用的对象,而不是等待 jvm 运行垃圾收集。

Substitute a weakreference system for your current soft reference system while testing.

The weak reference system will remove an objects with no other incoming references as soon as that happens, instead of waiting for the jvm to run garbage collection.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文