Skip to content
This repository was archived by the owner on Oct 1, 2025. It is now read-only.

Commit ad6cdea

Browse files
author
Poonam Bajaj
committed
8071507: (ref) Clear phantom reference as soft and weak references do
8143847: Remove REF_CLEANER reference category Reviewed-by: mchung, kbarrett, iris
1 parent d63ed0a commit ad6cdea

File tree

10 files changed

+122
-65
lines changed

10 files changed

+122
-65
lines changed

hotspot/src/share/vm/classfile/systemDictionary.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1907,12 +1907,11 @@ void SystemDictionary::initialize_preloaded_classes(TRAPS) {
19071907
InstanceKlass::cast(WK_KLASS(Reference_klass))->set_reference_type(REF_OTHER);
19081908
InstanceRefKlass::update_nonstatic_oop_maps(WK_KLASS(Reference_klass));
19091909

1910-
initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(Cleaner_klass), scan, CHECK);
1910+
initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(PhantomReference_klass), scan, CHECK);
19111911
InstanceKlass::cast(WK_KLASS(SoftReference_klass))->set_reference_type(REF_SOFT);
19121912
InstanceKlass::cast(WK_KLASS(WeakReference_klass))->set_reference_type(REF_WEAK);
19131913
InstanceKlass::cast(WK_KLASS(FinalReference_klass))->set_reference_type(REF_FINAL);
19141914
InstanceKlass::cast(WK_KLASS(PhantomReference_klass))->set_reference_type(REF_PHANTOM);
1915-
InstanceKlass::cast(WK_KLASS(Cleaner_klass))->set_reference_type(REF_CLEANER);
19161915

19171916
// JSR 292 classes
19181917
WKID jsr292_group_start = WK_KLASS_ENUM_NAME(MethodHandle_klass);

hotspot/src/share/vm/classfile/systemDictionary.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ class Ticks;
128128
do_klass(WeakReference_klass, java_lang_ref_WeakReference, Pre ) \
129129
do_klass(FinalReference_klass, java_lang_ref_FinalReference, Pre ) \
130130
do_klass(PhantomReference_klass, java_lang_ref_PhantomReference, Pre ) \
131-
do_klass(Cleaner_klass, sun_misc_Cleaner, Pre ) \
132131
do_klass(Finalizer_klass, java_lang_ref_Finalizer, Pre ) \
133132
\
134133
do_klass(Thread_klass, java_lang_Thread, Pre ) \

hotspot/src/share/vm/classfile/vmSymbols.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@
7979
template(java_lang_ref_WeakReference, "java/lang/ref/WeakReference") \
8080
template(java_lang_ref_FinalReference, "java/lang/ref/FinalReference") \
8181
template(java_lang_ref_PhantomReference, "java/lang/ref/PhantomReference") \
82-
template(sun_misc_Cleaner, "sun/misc/Cleaner") \
8382
template(java_lang_ref_Finalizer, "java/lang/ref/Finalizer") \
8483
template(java_lang_reflect_AccessibleObject, "java/lang/reflect/AccessibleObject") \
8584
template(java_lang_reflect_Method, "java/lang/reflect/Method") \

hotspot/src/share/vm/memory/referenceProcessor.cpp

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,6 @@ ReferenceProcessor::ReferenceProcessor(MemRegion span,
118118
_discoveredWeakRefs = &_discoveredSoftRefs[_max_num_q];
119119
_discoveredFinalRefs = &_discoveredWeakRefs[_max_num_q];
120120
_discoveredPhantomRefs = &_discoveredFinalRefs[_max_num_q];
121-
_discoveredCleanerRefs = &_discoveredPhantomRefs[_max_num_q];
122121

123122
// Initialize all entries to NULL
124123
for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
@@ -245,14 +244,7 @@ ReferenceProcessorStats ReferenceProcessor::process_discovered_references(
245244
{
246245
GCTraceTime tt("PhantomReference", trace_time, false, gc_timer, gc_id);
247246
phantom_count =
248-
process_discovered_reflist(_discoveredPhantomRefs, NULL, false,
249-
is_alive, keep_alive, complete_gc, task_executor);
250-
251-
// Process cleaners, but include them in phantom statistics. We expect
252-
// Cleaner references to be temporary, and don't want to deal with
253-
// possible incompatibilities arising from making it more visible.
254-
phantom_count +=
255-
process_discovered_reflist(_discoveredCleanerRefs, NULL, false,
247+
process_discovered_reflist(_discoveredPhantomRefs, NULL, true,
256248
is_alive, keep_alive, complete_gc, task_executor);
257249
}
258250

@@ -891,7 +883,6 @@ void ReferenceProcessor::balance_all_queues() {
891883
balance_queues(_discoveredWeakRefs);
892884
balance_queues(_discoveredFinalRefs);
893885
balance_queues(_discoveredPhantomRefs);
894-
balance_queues(_discoveredCleanerRefs);
895886
}
896887

897888
size_t
@@ -1051,9 +1042,6 @@ inline DiscoveredList* ReferenceProcessor::get_discovered_list(ReferenceType rt)
10511042
case REF_PHANTOM:
10521043
list = &_discoveredPhantomRefs[id];
10531044
break;
1054-
case REF_CLEANER:
1055-
list = &_discoveredCleanerRefs[id];
1056-
break;
10571045
case REF_NONE:
10581046
// we should not reach here if we are an InstanceRefKlass
10591047
default:
@@ -1319,17 +1307,6 @@ void ReferenceProcessor::preclean_discovered_references(
13191307
preclean_discovered_reflist(_discoveredPhantomRefs[i], is_alive,
13201308
keep_alive, complete_gc, yield);
13211309
}
1322-
1323-
// Cleaner references. Included in timing for phantom references. We
1324-
// expect Cleaner references to be temporary, and don't want to deal with
1325-
// possible incompatibilities arising from making it more visible.
1326-
for (uint i = 0; i < _max_num_q; i++) {
1327-
if (yield->should_return()) {
1328-
return;
1329-
}
1330-
preclean_discovered_reflist(_discoveredCleanerRefs[i], is_alive,
1331-
keep_alive, complete_gc, yield);
1332-
}
13331310
}
13341311
}
13351312

@@ -1398,7 +1375,6 @@ const char* ReferenceProcessor::list_name(uint i) {
13981375
case 1: return "WeakRef";
13991376
case 2: return "FinalRef";
14001377
case 3: return "PhantomRef";
1401-
case 4: return "CleanerRef";
14021378
}
14031379
ShouldNotReachHere();
14041380
return NULL;

hotspot/src/share/vm/memory/referenceProcessor.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,10 +264,9 @@ class ReferenceProcessor : public CHeapObj<mtGC> {
264264
DiscoveredList* _discoveredWeakRefs;
265265
DiscoveredList* _discoveredFinalRefs;
266266
DiscoveredList* _discoveredPhantomRefs;
267-
DiscoveredList* _discoveredCleanerRefs;
268267

269268
public:
270-
static int number_of_subclasses_of_ref() { return (REF_CLEANER - REF_OTHER); }
269+
static int number_of_subclasses_of_ref() { return (REF_PHANTOM - REF_OTHER); }
271270

272271
uint num_q() { return _num_q; }
273272
uint max_num_q() { return _max_num_q; }

hotspot/src/share/vm/memory/referenceType.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ enum ReferenceType {
3535
REF_SOFT, // Subclass of java/lang/ref/SoftReference
3636
REF_WEAK, // Subclass of java/lang/ref/WeakReference
3737
REF_FINAL, // Subclass of java/lang/ref/FinalReference
38-
REF_PHANTOM, // Subclass of java/lang/ref/PhantomReference
39-
REF_CLEANER // Subclass of sun/misc/Cleaner
38+
REF_PHANTOM // Subclass of java/lang/ref/PhantomReference
4039
};
4140

4241
#endif // SHARE_VM_MEMORY_REFRERENCETYPE_HPP

hotspot/src/share/vm/runtime/vmStructs.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,6 @@ typedef BinaryTreeDictionary<Metablock, FreeList<Metablock> > MetablockTreeDicti
671671
static_field(SystemDictionary, WK_KLASS(WeakReference_klass), Klass*) \
672672
static_field(SystemDictionary, WK_KLASS(FinalReference_klass), Klass*) \
673673
static_field(SystemDictionary, WK_KLASS(PhantomReference_klass), Klass*) \
674-
static_field(SystemDictionary, WK_KLASS(Cleaner_klass), Klass*) \
675674
static_field(SystemDictionary, WK_KLASS(Finalizer_klass), Klass*) \
676675
static_field(SystemDictionary, WK_KLASS(Thread_klass), Klass*) \
677676
static_field(SystemDictionary, WK_KLASS(ThreadGroup_klass), Klass*) \

jdk/src/share/classes/java/lang/ref/PhantomReference.java

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -29,23 +29,20 @@
2929
/**
3030
* Phantom reference objects, which are enqueued after the collector
3131
* determines that their referents may otherwise be reclaimed. Phantom
32-
* references are most often used for scheduling pre-mortem cleanup actions in
33-
* a more flexible way than is possible with the Java finalization mechanism.
32+
* references are most often used to schedule post-mortem cleanup actions.
3433
*
35-
* <p> If the garbage collector determines at a certain point in time that the
36-
* referent of a phantom reference is <a
37-
* href="package-summary.html#reachability">phantom reachable</a>, then at that
38-
* time or at some later time it will enqueue the reference.
34+
* <p> Suppose the garbage collector determines at a certain point in time
35+
* that an object is <a href="package-summary.html#reachability">
36+
* phantom reachable</a>. At that time it will atomically clear
37+
* all phantom references to that object and all phantom references to
38+
* any other phantom-reachable objects from which that object is reachable.
39+
* At the same time or at some later time it will enqueue those newly-cleared
40+
* phantom references that are registered with reference queues.
3941
*
4042
* <p> In order to ensure that a reclaimable object remains so, the referent of
4143
* a phantom reference may not be retrieved: The <code>get</code> method of a
4244
* phantom reference always returns <code>null</code>.
4345
*
44-
* <p> Unlike soft and weak references, phantom references are not
45-
* automatically cleared by the garbage collector as they are enqueued. An
46-
* object that is reachable via phantom references will remain so until all
47-
* such references are cleared or themselves become unreachable.
48-
*
4946
* @author Mark Reinhold
5047
* @since 1.2
5148
*/
@@ -69,8 +66,8 @@ public T get() {
6966
*
7067
* <p> It is possible to create a phantom reference with a <tt>null</tt>
7168
* queue, but such a reference is completely useless: Its <tt>get</tt>
72-
* method will always return null and, since it does not have a queue, it
73-
* will never be enqueued.
69+
* method will always return {@code null} and, since it does not have a queue,
70+
* it will never be enqueued.
7471
*
7572
* @param referent the object the new phantom reference will refer to
7673
* @param q the queue with which the reference is to be registered,

jdk/src/share/classes/java/lang/ref/package.html

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved.
2+
Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
33
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
55
This code is free software; you can redistribute it and/or modify it
@@ -46,8 +46,7 @@ <h2>Package Specification</h2>
4646
references are for implementing memory-sensitive caches, weak references are
4747
for implementing canonicalizing mappings that do not prevent their keys (or
4848
values) from being reclaimed, and phantom references are for scheduling
49-
pre-mortem cleanup actions in a more flexible way than is possible with the
50-
Java finalization mechanism.
49+
post-mortem cleanup actions.
5150

5251
<p> Each reference-object type is implemented by a subclass of the abstract
5352
base <code>{@link java.lang.ref.Reference}</code> class. An instance of one of
@@ -66,9 +65,10 @@ <h3>Notification</h3>
6665
<em>registering</em> an appropriate reference object with a <em>reference
6766
queue</em> at the time the reference object is created. Some time after the
6867
garbage collector determines that the reachability of the referent has changed
69-
to the value corresponding to the type of the reference, it will add the
70-
reference to the associated queue. At this point, the reference is considered
71-
to be <em>enqueued</em>. The program may remove references from a queue either
68+
to the value corresponding to the type of the reference, it will clear the
69+
reference and add it to the associated queue. At this point, the
70+
reference is considered to be <em>enqueued</em>. The program may remove
71+
references from a queue either
7272
by polling or by blocking until a reference becomes available. Reference
7373
queues are implemented by the <code>{@link java.lang.ref.ReferenceQueue}</code>
7474
class.
@@ -91,17 +91,6 @@ <h3>Notification</h3>
9191
checks an internal data structure, this check will add little overhead to the
9292
hashtable access methods.
9393

94-
95-
<h3>Automatically-cleared references</h3>
96-
97-
Soft and weak references are automatically cleared by the collector before
98-
being added to the queues with which they are registered, if any. Therefore
99-
soft and weak references need not be registered with a queue in order to be
100-
useful, while phantom references do. An object that is reachable via phantom
101-
references will remain so until all such references are cleared or themselves
102-
become unreachable.
103-
104-
10594
<a name="reachability"></a>
10695
<h3>Reachability</h3>
10796

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/**
25+
* @test
26+
* @bug 8071507
27+
* @summary Test that PhantomReferences are cleared when notified.
28+
* @run main/othervm PhantomReferentClearing
29+
*/
30+
31+
import java.lang.ref.PhantomReference;
32+
import java.lang.ref.ReferenceQueue;
33+
import java.util.ArrayList;
34+
import java.util.List;
35+
36+
public class PhantomReferentClearing {
37+
38+
private static final long ENQUEUE_TIMEOUT = 1000; // 1 sec, in millis
39+
40+
// P1 & P2 are PhantomReference objects
41+
// O1 & O2 are objects
42+
//
43+
// -> is a strong reference
44+
// => is a referent reference
45+
//
46+
// root -> P1
47+
// root -> P2
48+
// root -> O1
49+
// root -> O2
50+
// O1 -> O2
51+
// P1 => O1
52+
// P2 => O2
53+
//
54+
// (1) Remove root -> O1 and collect. P1 notified, P2 !notified.
55+
// (2) Remove root -> O2 and collect.
56+
//
57+
// If phantom references are cleared when notified, as proposed by
58+
// 8071507, then P2 should be notified, and the test passes.
59+
//
60+
// Otherwise, P2 does not get notified because it remains reachable
61+
// from O1, which is being retained by P1. This fails the test.
62+
63+
private static final ReferenceQueue<Object> Q1 = new ReferenceQueue<>();
64+
private static final ReferenceQueue<Object> Q2 = new ReferenceQueue<>();
65+
66+
private static volatile Object O2 = new Object();
67+
private static volatile List<Object> O1 = new ArrayList<>();
68+
static {
69+
O1.add(O2);
70+
}
71+
72+
private static final PhantomReference<Object> P1 = new PhantomReference<>(O1, Q1);
73+
private static final PhantomReference<Object> P2 = new PhantomReference<>(O2, Q2);
74+
75+
public static void main(String[] args) throws InterruptedException {
76+
77+
// Collect, and verify neither P1 or P2 notified.
78+
System.gc();
79+
if (Q1.remove(ENQUEUE_TIMEOUT) != null) {
80+
throw new RuntimeException("P1 already notified");
81+
} else if (Q2.poll() != null) {
82+
throw new RuntimeException("P2 already notified");
83+
}
84+
85+
// Delete root -> O1, collect, verify P1 notified, P2 not notified.
86+
O1 = null;
87+
System.gc();
88+
if (Q1.remove(ENQUEUE_TIMEOUT) == null) {
89+
throw new RuntimeException("P1 not notified by O1 deletion");
90+
} else if (Q2.remove(ENQUEUE_TIMEOUT) != null) {
91+
throw new RuntimeException("P2 notified by O1 deletion.");
92+
}
93+
94+
// Delete root -> O2, collect. P2 should be notified.
95+
O2 = null;
96+
System.gc();
97+
if (Q2.remove(ENQUEUE_TIMEOUT) == null) {
98+
throw new RuntimeException("P2 not notified by O2 deletion");
99+
}
100+
}
101+
}

0 commit comments

Comments
 (0)