Path: blob/master/test/hotspot/jtreg/vmTestbase/gc/gctests/OneeFinalizerTest/OneeFinalizerTest.java
41155 views
/*1* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @key stress randomness26*27* @summary converted from VM Testbase gc/gctests/OneeFinalizerTest.28* VM Testbase keywords: [gc, stress, stressopt, nonconcurrent, jrockit]29* VM Testbase readme:30* DESCRIPTION31* Regression test that verifies that only one finalizer gets called.32*33* COMMENTS34* This test was ported from JRockit test suite.35*36* @library /vmTestbase37* /test/lib38* @run main/othervm39* -XX:-UseGCOverheadLimit40* -Xlog:gc:gc.log41* gc.gctests.OneeFinalizerTest.OneeFinalizerTest42*/4344package gc.gctests.OneeFinalizerTest;4546import nsk.share.TestFailure;47import nsk.share.gc.GC;48import nsk.share.gc.GCTestBase;49import nsk.share.gc.gp.GarbageUtils;50import nsk.share.test.Stresser;5152/**53* Test that verifies that finalize() method is invoking only once.54*/55public class OneeFinalizerTest extends GCTestBase {5657private GlobalSafeCounter[] finalizerCounters = null;5859/**60* Helper class used for counting number of calls to finalizers.61*/62protected class GlobalSafeCounter {6364private int counter;6566/**67* Constructor that inits the global counter to 0.68*/69protected GlobalSafeCounter() {70counter = 0;71}7273/**74* Reset the global counter to 0.75*/76protected final void resetCounter() {77synchronized (this) {78counter = 0;79}80}8182/**83* Increase the global counter by 1.84*/85protected final void increaseCounter() {86synchronized (this) {87counter++;88}89}9091/**92* Retrieve the global counter value.93*94* @return value of the global counter95*/96protected final int getCounterValue() {97int value;9899synchronized (this) {100value = counter;101}102103return value;104}105}106107/**108* Helper class the implements finalize(), and that increments109* the global counters for each finalize() invokation.110*/111protected class FinalizedObject {112113private final int counterIndex;114115/**116* Constructor for the helper object which implements finalize().117*118* @param index Index for the counter in the global array, that119* corresponds to this object.120*/121protected FinalizedObject(int index) {122counterIndex = index;123}124125/**126* Increases the global counter for this object when finalize()127* gets called (to make sure each finalizer gets called onee).128*/129@Override130protected final void finalize() {131finalizerCounters[counterIndex].increaseCounter();132}133}134135private void initOneeFinalizerTest(int numberOfObjects) {136// NOTE: Set to null in case it's been used before (to prevent OOM)137finalizerCounters = null;138finalizerCounters = new GlobalSafeCounter[numberOfObjects];139140for (int i = 0; i < numberOfObjects; i++) {141finalizerCounters[i] = new GlobalSafeCounter();142}143}144145/**146* Tests that the finalize() method on each FinalizedObject instance147* has been called exactly one time.148*/149@Override150public void run() {151152153int numberOfObjects = 2000;154155initOneeFinalizerTest(numberOfObjects);156157FinalizedObject[] testObjects = new FinalizedObject[numberOfObjects];158159// creates garbage160for (int i = 0; i < numberOfObjects; i++) {161testObjects[i] = new FinalizedObject(i);162}163164if (testObjects[0].hashCode() == 212_85_06) {165System.out.println("Bingo!!!");166}167168testObjects = null;169170Stresser stresser = new Stresser(runParams.getStressOptions());171stresser.start(0);172/* force finalization */173GarbageUtils.eatMemory(stresser);174if (!stresser.continueExecution()) {175// may be we didn't eat all memory and didn't provoke GC176System.out.println("Passed without check");177return;178}179System.gc();180System.runFinalization();181System.gc();182System.runFinalization();183System.gc();184185int numberOfFinalizersRunMoreThanOnce = 0;186int numberOfFinalizersNotRun = 0;187188for (int i = 0; i < numberOfObjects; i++) {189int counter = finalizerCounters[i].getCounterValue();190if (counter > 1) {191numberOfFinalizersRunMoreThanOnce++;192System.err.println("Object #" + i + " counter = " + counter);193} else if (counter == 0) {194System.err.println("WARNING: Finalizer not run for object #" + i);195numberOfFinalizersNotRun++;196}197}198199if (numberOfFinalizersNotRun > 0) {200System.err.println("WARNING: " + numberOfFinalizersNotRun + " finalizers not run");201}202203if (numberOfFinalizersRunMoreThanOnce != 0) {204throw new TestFailure("OneeFinalizerTest failed. " + numberOfFinalizersRunMoreThanOnce + " errors");205}206System.out.println("Test passed.");207}208209public static void main(String[] args) {210GC.runTest(new OneeFinalizerTest(), args);211}212}213214215