1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package dalvik.annotation.optimization; 18 19 import java.lang.annotation.ElementType; 20 import java.lang.annotation.Retention; 21 import java.lang.annotation.RetentionPolicy; 22 import java.lang.annotation.Target; 23 24 /** 25 * Allow the implementation to eliminate object references that are no longer needed, just as it 26 * would eliminate other dead variables. 27 * 28 * The annotation applies to methods of the annotated class, and to methods declared in any inner 29 * class declared inside the annotated class. It does not apply to methods declared in subclasses 30 * or superclasses. It is ignored for interfaces. 31 * 32 * The annotation promises that the implementation of this class remains correct if objects are 33 * finalized, and java.lang.ref References are enqueued, as soon as the JLS allows them to be, 34 * i.e. after they are allowed to be marked as unreachable according to the JLS. Historically, the 35 * Android runtime has garbage collected objects later than the JLS would allow, by retaining 36 * objects references that are no longer needed. Some classes that implement finalize() or make 37 * use of java.lang.ref APIs may have grown to depend on this historic Android runtime behavior. 38 * 39 * For example, consider the method 40 * 41 * <pre> {@code 42 * void m() { 43 * long tmpNativePtr = this.nativePtrField; 44 * foo(tmpNativePtr); 45 * }}</pre> 46 * 47 * where foo() accesses the memory M referenced by {@code this.nativePtrField}. Once {@code 48 * tmpNativePtr} is computed, this object itself is no longer needed, and may be unreachable by JLS 49 * rules. This may cause this object to be finalized, and M to be deleted, while {@code foo()} is 50 * still running and accessing M. 51 * 52 * Historically, ART has avoided this by keeping "this" reachable until {@code m()} completes. 53 * (Class file and dex level tools may not always do the same.) With this annotation, the Android 54 * runtime may no longer retain the "this" reference, again making the erroneous early 55 * finalization possible. 56 * 57 * The above example code could be made safe to annotate with {@code DeadReferenceSafe} by either 58 * adding Reference.reachabilityFence(this) to the end of {@code m()} and similar methods, or 59 * (Android-only) by declaring nativePtrField with a {@code @ReachabilitySensitive} annotation. 60 * 61 * The annotation will normally be safe for classes that do not use or rely on finalization-like 62 * cleanup mechanisms. It is unlikely to be safe for classes that use {@code java.lang.ref} or 63 * finalization but never mention {@code reachabilityFence()} or {@code @ReachabilitySensitive}. 64 * 65 * When it is safe, this annotation might result in better performance because more memory can be 66 * reclaimed earlier by the garbage collector. 67 * 68 * Since this is technically safe for all classes that follow Java language rules, we expect this 69 * to eventually become the default. This annotation allows us to selectively enable dead 70 * reference elimination during the transition, and while the details of {@code 71 * @ReachabilitySensitive} (like its name) are in flux. 72 * 73 * @hide 74 */ 75 @Retention(RetentionPolicy.RUNTIME) // Let the GC or interpreter ask, if they need to. 76 @Target({ElementType.TYPE}) 77 public @interface DeadReferenceSafe {} 78