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 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
WeakReferenceto 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.