JVM - Are WeakReferences collected in minor GC?

前端 未结 6 1040
情歌与酒
情歌与酒 2021-01-05 11:06

I was wondering about that since that would make them less useful. If so, is there a way to make memory weakly referenced only \"garbage\" on major GC?

相关标签:
6条回答
  • 2021-01-05 11:16

    Some insights from Brian Goetz (article from 2006) that still seems in viguor:

    Weak References

    Soft References -> interesting details in the [A poor man's cache] and [How the garbage collector handles References] paragraphs.

    0 讨论(0)
  • 2021-01-05 11:19

    It will depend if the WeakReference object is in Eden or not - a minor collection will only look at objects in Eden.

    0 讨论(0)
  • 2021-01-05 11:25

    You may be thinking of SoftReferences which may be closer to what you want.

    Minor collections will collect any object in the young space. A WeakReference to an object in the young space will be collected on a minor GC. A WeakReference to an object in the tenured space will be collected on tenured collection e.g. Full GC. BTW You can have concurrent collections of only the tenured space.

    0 讨论(0)
  • 2021-01-05 11:27

    The javadoc does not specifically state what the "timescales" are for clearing / breaking WeakReferences. That would make the answer to your question (at least in theory) "it is implementation dependent". Indeed, the JLS spec and javadocs don't even mention major versus minor collections. The whole topic comes is in the "implementation details" category.

    If you do want references that are GC sensitive, then maybe you should use a SoftReference instead. That is described as follows:

    "All soft references to softly-reachable objects are guaranteed to have been cleared before the virtual machine throws an OutOfMemoryError. Otherwise no constraints are placed upon the time at which a soft reference will be cleared or the order in which a set of such references to different objects will be cleared. Virtual machine implementations are, however, encouraged to bias against clearing recently-created or recently-used soft references."

    Elsewhere, a soft reference is described as stronger than a weak reference. The implication is that it is less likely to be broken; e.g. by an over-eager garbage collector. But note that none of this talks about major vs minor garbage collections.


    UPDATE I researched the following (highly plausible!) claim in https://stackoverflow.com/a/16977182/139985 in the Java 11 source tree:

    Minor collections will collect any object in the young space. A WeakReference to an object in the young space will be collected on a minor GC.

    The native Reference handling code is complicated. There is a general ReferenceProcessor class that does the following:

    • It selectively records Reference objects that a GC encounters. The GC code calls ReferenceProcessor::discover_reference to make this happen.
    • It iterates the discovered Reference objects to determine whether or not to break the references. The relevant Reference objects are added to their respective reference queues.

    The complications are as follows:

    • A GC may or may not call ReferenceProcessor::discover_reference. From what I can tell, most (if not all) GCs do call it, but it is hard to be sure.

    • The ReferenceProcessor has different policies for dealing with the case where the reference and referent are in different generations (or spans). (If a reference is not going to processed, the referent will be treated as hard reachable for the current collection.)

    In short, I can confirm that Reference objects will typically be processed in a minor GC. However, the actual behavior a particular Reference may depend on generation / span issues.

    (It should be possible to observe the general behavior for a particular GC from the GC logs. Look for the stats or timings for reference processing phases.)


    1 - The "span" term is used in comments. I think it relates to collectors (e.g. G1) that break the old generation into a number of regions (spans) that are collected separately.

    0 讨论(0)
  • 2021-01-05 11:29

    WeakReference does not prevent collection of object, so if object belongs to young space and reachable only by weak references it will be collected.

    SoftReferences (in HotSpot JVM) act either as weak or strong references dependent on last access timestamps (timestamp of last call to get() on reference). 'Expiry time' of sotf reference is calculated as free memory size multiplied by coefficient configured via -XX:SoftRefLRUPolicyMSPerMB=T (e.g. less free memory, short expiry of soft references).

    Generally, using JVM references for caching is a bad idea: - it promotes temporary objects to old space, breaking weak generational hypothesis - references are threat in special way by GC increasing minor GC time

    If you need cache with eviction strategy it is better to implement it explicitly and account for effecting memory footprint of stored data in eviction policy.

    0 讨论(0)
  • 2021-01-05 11:31

    Why do you want that? Your program shouldn't care much about major vs minor GC cycles, and in fact that sort of differentiation won't even exist in all JVMs / GC configurations.

    WeakReferences are collectable as soon as there are no strong references to the object. This could include minor GCs.

    If you want the object to stick around for a while until there is actual memory pressure, try SoftReference instead.

    0 讨论(0)
提交回复
热议问题