1 /* 2 * Copyright (c) 2002, 2018, 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 * @key stress gc 27 * 28 * @summary converted from VM Testbase gc/gctests/FinalizeTest01. 29 * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent, monitoring] 30 * 31 * @library /vmTestbase 32 * /test/lib 33 * @run driver jdk.test.lib.FileInstaller . . 34 * @run main/othervm -XX:-UseGCOverheadLimit gc.gctests.FinalizeTest01.FinalizeTest01 35 */ 36 37 package gc.gctests.FinalizeTest01; 38 39 import java.lang.management.ManagementFactory; 40 import java.lang.management.MemoryMXBean; 41 import nsk.share.gc.*; 42 import nsk.share.TestFailure; 43 import nsk.share.test.ExecutionController; 44 import nsk.share.test.Stresser; 45 46 /** 47 * Tests that GC works correctly with finalizers. 48 * 49 * Create a number of objects, some of which register their 50 * creation/finalization. Then try to eat available memory 51 * which forces garbage collection of created objects. 52 * Garbage collector should try to collect the garbage and thus 53 * call finalizers. The test checks that all finalizers have been called. 54 */ 55 56 /* 57 Reworked original test (4933478). Original comment: 58 59 Tests that objects w/finalizers will eventually finalize 60 (and by the way, the system doesn't crash!). 61 62 Returns exit code 0 on success, and 1 on failure. 63 64 */ 65 /** 66 * Class with finalizer that throws Exception. 67 * Used for FinalizeTest02 68 */ 69 class FinExceptMemoryObject extends FinMemoryObject { 70 71 public FinExceptMemoryObject(int size) { 72 super(size); 73 } 74 75 protected void finalize() { 76 super.finalize(); 77 throw new RuntimeException("Exception in finalizer"); 78 } 79 } 80 81 public class FinalizeTest01 extends GCTestBase { 82 83 private final int allocRatio = 5; 84 private final int size = 1024 * 2; 85 private int count = 1000; 86 private static boolean throwExceptions = false; 87 private ExecutionController stresser; 88 89 private void runOne() { 90 Object o; 91 for (int i = 0; i < count; i++) { 92 if (i % allocRatio == 0) { 93 if (throwExceptions) { 94 o = new FinExceptMemoryObject(size); 95 } else { 96 o = new FinMemoryObject(size); 97 } 98 } else { 99 o = new byte[size - Memory.getObjectExtraSize()]; 100 } 101 } 102 o = null; 103 104 MemoryMXBean mbean = ManagementFactory.getMemoryMXBean(); 105 long finalizationMaxTime = 1000 * 60; // 1min 106 107 /* Provoke GC to start finalization. */ 108 Algorithms.eatMemory(stresser); 109 if (!stresser.continueExecution()) { 110 // we did not eat all memory 111 return; 112 } 113 long waitTime = System.currentTimeMillis() + finalizationMaxTime; 114 115 /* 116 * Before we force finalization it is needed to check that we have 117 * any object pending for finazlization. If not then is a GC bug. 118 */ 119 while (FinMemoryObject.getFinalizedCount() 120 + mbean.getObjectPendingFinalizationCount() == 0 121 && (System.currentTimeMillis() < waitTime)) { 122 System.out.println("No objects are found in the finalization queue. Waiting.."); 123 try { 124 Thread.sleep(1000); 125 } catch (InterruptedException ie) { 126 } 127 } 128 if (FinMemoryObject.getFinalizedCount() 129 + mbean.getObjectPendingFinalizationCount() == 0) { 130 throw new TestFailure("Test failed. (No objects were not queued for finalization during 1min)"); 131 } 132 133 /* force finalization and wait for it finishs */ 134 Runtime.getRuntime().runFinalization(); 135 136 boolean error = (FinMemoryObject.getLiveCount() != 0); 137 138 /* 139 * The runFinalization() starts the second finalization thread and wait until it finishs. 140 * However it is a very little probability (less then 1%) that not all object are finalized yet. 141 * Possibly the regular Finalizer thread have not finished its work when we check getLiveCount() 142 * or GC is still clearing memory and adding objects to the queue. 143 */ 144 waitTime = System.currentTimeMillis() + finalizationMaxTime; 145 while (error && (System.currentTimeMillis() < waitTime)) { 146 // wait 1 sec (it could be less due to potential InterruptedException) 147 try { 148 Thread.sleep(1000); 149 } catch (InterruptedException ie) { 150 } 151 error = (FinMemoryObject.getLiveCount() != 0); 152 } 153 154 if (error) { 155 throw new TestFailure("Test failed (objects were not finalized during 1min)"); 156 } 157 158 159 System.out.println("Allocated: " + FinMemoryObject.getAllocatedCount()); 160 System.out.println("Finalized: " + FinMemoryObject.getFinalizedCount()); 161 error = (FinMemoryObject.getLiveCount() != 0); 162 if (error) { 163 throw new TestFailure("Test failed."); 164 } 165 } 166 167 public void run() { 168 stresser = new Stresser(runParams.getStressOptions()); 169 stresser.start(runParams.getIterations()); 170 count = (int) Math.min(runParams.getTestMemory() / size, Integer.MAX_VALUE); 171 System.out.println("Allocating " + count 172 + " objects. 1 out of " + allocRatio 173 + " will have a finalizer."); 174 System.out.flush(); 175 runOne(); 176 } 177 178 public static void main(String[] args) { 179 for (int i = 0; i < args.length; ++i) { 180 if (args[i].equals("-throwExceptions")) { 181 throwExceptions = true; 182 } 183 } 184 GC.runTest(new FinalizeTest01(), args); 185 } 186 }