15d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao/*
25d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Copyright (C) 2008 The Android Open Source Project
35d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao *
45d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Licensed under the Apache License, Version 2.0 (the "License");
55d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * you may not use this file except in compliance with the License.
65d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * You may obtain a copy of the License at
75d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao *
85d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao *      http://www.apache.org/licenses/LICENSE-2.0
95d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao *
105d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Unless required by applicable law or agreed to in writing, software
115d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * distributed under the License is distributed on an "AS IS" BASIS,
125d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * See the License for the specific language governing permissions and
145d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * limitations under the License.
155d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */
165d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
175d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.lang.ref.*;
185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaopublic class InternedString {
205d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public static final String CONST = "Class InternedString";
215d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
225d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public static void run() {
235d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("InternedString.run");
245d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        testImmortalInternedString();
255d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        testDeadInternedString();
265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
275d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2812100a534aa9d5819de87586f53631642ab0f364Ian Rogers    private static WeakReference<String> makeWeakString() {
295d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        String s = "blah";
305d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        s = s + s;
3112100a534aa9d5819de87586f53631642ab0f364Ian Rogers        WeakReference<String> strRef = new WeakReference<String>(s.intern());
3212100a534aa9d5819de87586f53631642ab0f364Ian Rogers        return strRef;
3312100a534aa9d5819de87586f53631642ab0f364Ian Rogers    }
3412100a534aa9d5819de87586f53631642ab0f364Ian Rogers
3512100a534aa9d5819de87586f53631642ab0f364Ian Rogers    private static void testDeadInternedString() {
3612100a534aa9d5819de87586f53631642ab0f364Ian Rogers        WeakReference<String> strRef = makeWeakString();
377befd0e35bbed32b90bc0c8b6d3fa8bd612f5506Mathieu Chartier        Runtime.getRuntime().gc();
385d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        // "blahblah" should disappear from the intern list
39795d78f4d04c8d007bf2bdf2ed4131379bcf19c7jeffhao        Main.assertTrue(strRef.get() == null);
405d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
415d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
425d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    private static void testImmortalInternedString() {
435d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        WeakReference strRef = new WeakReference<String>(CONST.intern());
447befd0e35bbed32b90bc0c8b6d3fa8bd612f5506Mathieu Chartier        Runtime.getRuntime().gc();
455d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        // Class constant string should be entered to the interned table when
465d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        // loaded
47795d78f4d04c8d007bf2bdf2ed4131379bcf19c7jeffhao        Main.assertTrue(CONST == CONST.intern());
485d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        // and it should survive the gc
49795d78f4d04c8d007bf2bdf2ed4131379bcf19c7jeffhao        Main.assertTrue(strRef.get() != null);
505d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
515d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        String s = CONST;
525d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        // "Class InternedString" should remain on the intern list
535d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        strRef = new WeakReference<String>(s.intern());
545d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        // Kill s, otherwise the string object is still accessible from root set
555d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        s = "";
567befd0e35bbed32b90bc0c8b6d3fa8bd612f5506Mathieu Chartier        Runtime.getRuntime().gc();
57795d78f4d04c8d007bf2bdf2ed4131379bcf19c7jeffhao        Main.assertTrue(strRef.get() == CONST);
585d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
595d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao}
60