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?
The javadoc does not specifically state what the "timescales" are for clearing / breaking WeakReference
s. 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:
Reference
objects that a GC encounters. The GC code calls ReferenceProcessor::discover_reference
to make this happen.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.
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.
WeakReference
s 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.
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.
It will depend if the WeakReference object is in Eden or not - a minor collection will only look at objects in Eden.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With