JVM - Are WeakReferences collected in minor GC?

我只是一个虾纸丫 提交于 2020-05-08 03:39:40

问题


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?


回答1:


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.




回答2:


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.




回答3:


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.




回答4:


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




回答5:


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.




回答6:


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.



来源:https://stackoverflow.com/questions/16974776/jvm-are-weakreferences-collected-in-minor-gc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!