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 /*
  26  * @test
  27  * @key gc
  28  *
  29  * @summary converted from VM Testbase gc/gctests/FinalizerGC01.
  30  * VM Testbase keywords: [gc]
  31  * VM Testbase readme:
  32  * This rather contrived test checks the interplay of garbage collection
  33  * and finalizers. Just before a 0.5 Meg linked list is garbage collected,
  34  * the finalizer generates more garbage . The test fails if an OutOfMemoryError
  35  * is thrown.
  36  *
  37  * @library /vmTestbase
  38  *          /test/lib
  39  * @run driver jdk.test.lib.FileInstaller . .
  40  * @run main/othervm gc.gctests.FinalizerGC01.FinalizerGC01
  41  */
  42 
  43 package gc.gctests.FinalizerGC01;
  44 
  45 import nsk.share.TestFailure;
  46 
  47 class node {
  48         byte [] arr;
  49         node next;
  50         node prev;
  51         node(int info){ arr = new byte[128]; }
  52 }
  53 
  54 class CircularLinkedList{
  55         private void addElement(int info) {
  56                 node newnode;
  57                 newnode = new node(info);
  58                 if (Root == null){
  59                         Root = newnode;
  60                         Root.next = Root;
  61                         Root.prev = Root;
  62                 } else{
  63                         newnode.next = Root.next;
  64                         Root.next.prev = newnode;
  65                         Root.next = newnode;
  66                         newnode.prev = Root;
  67                 }
  68         }
  69         int elementCount() {
  70                 node p;
  71                 int count;
  72                 p = Root;
  73                 count = 0;
  74                 do {
  75                         p = p.prev;
  76                         count++;
  77                 }while(p != Root);
  78                 return count;
  79         }
  80         public void build1MegList() {
  81                 for (int i = 0 ; i < NELEMENTS ; i++)
  82                         addElement(i);
  83         }
  84         node Root=null;
  85         static final int NELEMENTS=4096;
  86 }
  87 class CircularLinkedListFinal extends CircularLinkedList {
  88         protected void finalize () {
  89                 CircularLinkedList cl = null;
  90                 // generate 1.5Meg more garbage
  91                 int i = 0;
  92                 int gcFails=0;
  93                 while (i < 3){
  94                         Root = null;
  95                         gcFails=0;
  96                         while (gcFails < NGCFAILS) {
  97                                 try {
  98                                         cl = new CircularLinkedList();
  99                                         cl.build1MegList();
 100                                         cl = null;
 101                                         break;
 102                                 }
 103                                 catch (OutOfMemoryError e) {
 104                                         System.gc();
 105                                         gcFails++;
 106                                 }
 107                         }
 108                         if (gcFails >= NGCFAILS) break;
 109                         i++;
 110                 }
 111                 if (i < 3) throw new OutOfMemoryError();
 112         }
 113         private static final int NGCFAILS=10;
 114 }
 115 
 116 public class FinalizerGC01 {
 117         public static void main(String args[]) {
 118                 int count = 0;
 119                 int gcFails = 0;
 120                 CircularLinkedListFinal cl = null;
 121                 while (count < 64) {
 122                         gcFails = 0;
 123                         while (gcFails<NGCFAILS) {
 124                                 try {
 125                                         cl = new CircularLinkedListFinal();
 126                                         cl.build1MegList();
 127                                         doComputation();
 128                                         cl = null;
 129                                         break;
 130                                 } catch (OutOfMemoryError e) {
 131                                         gcFails++;
 132                                         System.gc();
 133                                 }
 134                         }
 135                         if (gcFails >= NGCFAILS) break;
 136                         count++;
 137                 }
 138                 if (count < 64)
 139                         throw new TestFailure("Test failed on " + count + " iteration");
 140                 else
 141                         System.out.println("Test Passed");
 142         }
 143         static void doComputation(){
 144                 long i = 0;
 145                 while ( i < 1000000L) { i++; }
 146         }
 147         private static final int NGCFAILS=10;
 148 }