16a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson/* 26a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson * Copyright (C) 2011 Google Inc. 36a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson * 46a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 56a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson * you may not use this file except in compliance with the License. 66a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson * You may obtain a copy of the License at 76a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson * 86a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 96a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson * 106a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson * Unless required by applicable law or agreed to in writing, software 116a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 126a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson * See the License for the specific language governing permissions and 146a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson * limitations under the License. 156a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson */ 166a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson 176a22fa91a64739523c1344023f6dfde57e53110eJesse Wilsonpackage libcore.java.lang.ref; 186a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson 1964c6c367497c7fcf88e7527022234043e4460758Jesse Wilsonimport java.util.concurrent.CountDownLatch; 206a22fa91a64739523c1344023f6dfde57e53110eJesse Wilsonimport java.util.concurrent.atomic.AtomicBoolean; 219429d06c5427a6cac499ba90f138afac006135a2Jesse Wilsonimport java.util.concurrent.atomic.AtomicInteger; 226a22fa91a64739523c1344023f6dfde57e53110eJesse Wilsonimport junit.framework.TestCase; 236a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson 246a22fa91a64739523c1344023f6dfde57e53110eJesse Wilsonpublic final class FinalizeTest extends TestCase { 256a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson 266a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson public void testFinalizeIsCalled() throws Exception { 276a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson AtomicBoolean finalized = new AtomicBoolean(); 286a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson createFinalizableObject(finalized); 296a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson 301a9cff8f68deffd618c5cba1f22f0fb0e396e067Jesse Wilson FinalizationTester.induceFinalization(); 316a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson if (!finalized.get()) { 323edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson fail("object not yet finalized"); 333edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson } 343edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson } 353edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson 363edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson /** 373edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson * Test verifies that runFinalization() does not mess up objects 383edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson * that should be finalized later on. http://b/6907299 393edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson */ 403edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson public void testInducedFinalization() throws Exception { 413edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson AtomicBoolean finalized1 = new AtomicBoolean(); 423edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson AtomicBoolean finalized2 = new AtomicBoolean(); 433edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson createFinalizableObject(finalized1); 443edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson createFinalizableObject(finalized2); 453edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson FinalizationTester.induceFinalization(); 463edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson if (!finalized1.get() || !finalized2.get()) { 473edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson fail("not yet finalized: " + finalized1.get() + " " + finalized2.get()); 486a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson } 496a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson } 506a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson 511a9cff8f68deffd618c5cba1f22f0fb0e396e067Jesse Wilson /** Do not inline this method; that could break non-precise GCs. See FinalizationTester. */ 523edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson private X createFinalizableObject(final AtomicBoolean finalized) { 533edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson X result = new X() { 546a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson @Override protected void finalize() throws Throwable { 556a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson super.finalize(); 566a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson finalized.set(true); 576a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson } 586a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson }; 593edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson FinalizationTester.induceFinalization(); 603edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson // Dance around a bit to discourage dx from realizing that 'result' is no longer live. 613edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson boolean wasFinalized = finalized.get(); 623edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson if (wasFinalized) { 633edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson fail("finalizer called early"); // ...because 'result' is still live until we return. 643edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson } 653edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson // But we don't actually want to return 'result' because then we'd have to worry about 663edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson // the caller accidentally keeping it live. 673edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson return wasFinalized ? result : null; 686a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson } 696a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson 706a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson static class X {} 716a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson 7229e0638aca737dd1093dac55216982b5af7d59a7Jesse Wilson // http://b/issue?id=2136462 736a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson public void testBackFromTheDead() throws Exception { 746a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson try { 756a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson new ConstructionFails(); 766a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson } catch (AssertionError expected) { 776a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson } 786a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson 791a9cff8f68deffd618c5cba1f22f0fb0e396e067Jesse Wilson FinalizationTester.induceFinalization(); 8029e0638aca737dd1093dac55216982b5af7d59a7Jesse Wilson assertTrue("object whose constructor threw was not finalized", ConstructionFails.finalized); 816a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson } 826a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson 836a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson static class ConstructionFails { 8429e0638aca737dd1093dac55216982b5af7d59a7Jesse Wilson private static boolean finalized; 856a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson 866a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson ConstructionFails() { 876a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson throw new AssertionError(); 886a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson } 896a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson 906a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson @Override protected void finalize() throws Throwable { 9129e0638aca737dd1093dac55216982b5af7d59a7Jesse Wilson finalized = true; 926a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson } 936a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson } 9464c6c367497c7fcf88e7527022234043e4460758Jesse Wilson 9564c6c367497c7fcf88e7527022234043e4460758Jesse Wilson /** 9664c6c367497c7fcf88e7527022234043e4460758Jesse Wilson * The finalizer watch dog exits the VM if any object takes more than 10 s 9764c6c367497c7fcf88e7527022234043e4460758Jesse Wilson * to finalize. Check that objects near that limit are okay. 9864c6c367497c7fcf88e7527022234043e4460758Jesse Wilson */ 9964c6c367497c7fcf88e7527022234043e4460758Jesse Wilson public void testWatchdogDoesNotFailForObjectsThatAreNearTheDeadline() throws Exception { 10064c6c367497c7fcf88e7527022234043e4460758Jesse Wilson CountDownLatch latch = new CountDownLatch(5); 10164c6c367497c7fcf88e7527022234043e4460758Jesse Wilson createSlowFinalizer( 1, latch); 10264c6c367497c7fcf88e7527022234043e4460758Jesse Wilson createSlowFinalizer(1000, latch); 10364c6c367497c7fcf88e7527022234043e4460758Jesse Wilson createSlowFinalizer(2000, latch); 10464c6c367497c7fcf88e7527022234043e4460758Jesse Wilson createSlowFinalizer(4000, latch); 10564c6c367497c7fcf88e7527022234043e4460758Jesse Wilson createSlowFinalizer(8000, latch); 1061a9cff8f68deffd618c5cba1f22f0fb0e396e067Jesse Wilson FinalizationTester.induceFinalization(); 10764c6c367497c7fcf88e7527022234043e4460758Jesse Wilson latch.await(); 10864c6c367497c7fcf88e7527022234043e4460758Jesse Wilson } 10964c6c367497c7fcf88e7527022234043e4460758Jesse Wilson 11064c6c367497c7fcf88e7527022234043e4460758Jesse Wilson public void createSlowFinalizer(final long millis, final CountDownLatch latch) { 11164c6c367497c7fcf88e7527022234043e4460758Jesse Wilson new Object() { 11264c6c367497c7fcf88e7527022234043e4460758Jesse Wilson @Override protected void finalize() throws Throwable { 11364c6c367497c7fcf88e7527022234043e4460758Jesse Wilson System.out.println("finalize sleeping " + millis + " ms"); 11464c6c367497c7fcf88e7527022234043e4460758Jesse Wilson Thread.sleep(millis); 11564c6c367497c7fcf88e7527022234043e4460758Jesse Wilson latch.countDown(); 11664c6c367497c7fcf88e7527022234043e4460758Jesse Wilson } 11764c6c367497c7fcf88e7527022234043e4460758Jesse Wilson }; 11864c6c367497c7fcf88e7527022234043e4460758Jesse Wilson } 1199429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson 1209429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson /** 1219429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson * Make sure that System.runFinalization() returns even if the finalization 1229429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson * queue is never completely empty. http://b/4193517 1239429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson */ 1249429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson public void testSystemRunFinalizationReturnsEvenIfQueueIsNonEmpty() throws Exception { 1259429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson AtomicInteger count = new AtomicInteger(); 1269429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson AtomicBoolean keepGoing = new AtomicBoolean(true); 1279429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson createChainedFinalizer(count, keepGoing); 1281a9cff8f68deffd618c5cba1f22f0fb0e396e067Jesse Wilson FinalizationTester.induceFinalization(); 1299429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson keepGoing.set(false); 1309429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson assertTrue(count.get() > 0); 1319429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson } 1329429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson 1339429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson public void createChainedFinalizer(final AtomicInteger counter, final AtomicBoolean keepGoing) { 1349429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson new Object() { 1359429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson @Override protected void finalize() throws Throwable { 1369429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson int count = counter.incrementAndGet(); 1379429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson System.out.println(count); 1389429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson if (keepGoing.get()) { 1399429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson createChainedFinalizer(counter, keepGoing); // recursive! 1409429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson } 1419429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson System.gc(); 1421a9cff8f68deffd618c5cba1f22f0fb0e396e067Jesse Wilson FinalizationTester.enqueueReferences(); 1439429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson } 1449429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson }; 1459429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson } 1466a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson} 147