1 /*
2  * Copyright (c) 2007, 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 package vm.gc.compact;
24 
25 import java.util.*;
26 
27 import java.util.concurrent.atomic.AtomicInteger;
28 import nsk.share.test.*;
29 import nsk.share.gc.*;
30 import nsk.share.gc.gp.*;
31 
32 /**
33  * Test garbage collector compaction.
34  *
35  * The test starts several threads which create objects using
36  * given garbage producer until OOM. The references are kept
37  * in an array. The references to even elements are cleared
38  * and objects of larger size are created until OOM. The garbage
39  * collector will have to compact free space to free memory for
40  * new objects.
41  *
42  * The size of the second half of created objects could be set explictly.
43  *
44  * This process is repeated.
45  */
46 public class Compact extends ThreadedGCTest implements GarbageProducerAware, GarbageProducer1Aware, MemoryStrategyAware {
47 
48     private GarbageProducer garbageProducer;
49     private GarbageProducer garbageProducer1;
50     private MemoryStrategy memoryStrategy;
51     private long size;
52     private long size2;
53     private static long customSize = 0;
54     static AtomicInteger allocations = new AtomicInteger();
55 
56     private class Worker implements Runnable {
57 
58         private List<Object> bricks;
59         private ExecutionController stresser;
60 
run()61         public void run() {
62             if (stresser == null) {
63                 stresser = getExecutionController();
64             }
65             try {
66                 bricks = new ArrayList<Object>();
67                 while (stresser.continueExecution()) {
68                     bricks.add(garbageProducer.create(size));
69                 }
70             } catch (OutOfMemoryError e) {
71             }
72             if (bricks == null) {
73                 return;
74             }
75             int count = bricks.size();
76             for (int i = 0; stresser.continueExecution() && i < count; i += 2) {
77                 bricks.set(i, null);
78             }
79             try {
80                 for (int i = 0; stresser.continueExecution() && i < count; i += 2) {
81                     bricks.set(i, garbageProducer1.create(size2));
82                     allocations.incrementAndGet();
83                 }
84             } catch (OutOfMemoryError e) {
85             }
86             bricks = null;
87         }
88     }
89 
createRunnable(int i)90     public Runnable createRunnable(int i) {
91         return new Worker();
92     }
93 
run()94     public void run() {
95         size = memoryStrategy.getSize(runParams.getTestMemory());
96         size2 = customSize == 0
97                 ? size2 = size * 2
98                 : customSize;
99         super.run();
100     }
101 
setGarbageProducer(GarbageProducer garbageProducer)102     public final void setGarbageProducer(GarbageProducer garbageProducer) {
103         this.garbageProducer = garbageProducer;
104     }
105 
setGarbageProducer1(GarbageProducer garbageProducer1)106     public final void setGarbageProducer1(GarbageProducer garbageProducer1) {
107         this.garbageProducer1 = garbageProducer1;
108     }
109 
setMemoryStrategy(MemoryStrategy memoryStrategy)110     public final void setMemoryStrategy(MemoryStrategy memoryStrategy) {
111         this.memoryStrategy = memoryStrategy;
112     }
113 
setHumongousSizeFromParams(String[] args)114     static void setHumongousSizeFromParams(String[] args) {
115         for (int i = 0; i < args.length; ++i) {
116             if (args[i].equals("-size2")) {
117                 customSize = Long.parseLong(args[i + 1]);
118                 return;
119             }
120         }
121     }
122 
main(String[] args)123     public static void main(String[] args) {
124         setHumongousSizeFromParams(args);
125         GC.runTest(new Compact(), args);
126     }
127 }
128