001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tctest.longrunning;
005:
006: import com.tc.logging.LogLevel;
007: import com.tc.logging.TCLogger;
008: import com.tc.object.config.ConfigVisitor;
009: import com.tc.object.config.DSOApplicationConfig;
010: import com.tc.object.config.DSOClientConfigHelper;
011: import com.tc.object.config.TransparencyClassSpec;
012: import com.tc.simulator.app.Application;
013: import com.tc.simulator.app.ApplicationConfig;
014: import com.tc.simulator.listener.ListenerProvider;
015: import com.tc.simulator.listener.StatsListener;
016:
017: import java.io.CharArrayWriter;
018: import java.io.PrintStream;
019: import java.io.PrintWriter;
020: import java.text.DateFormat;
021: import java.text.NumberFormat;
022: import java.util.ArrayList;
023: import java.util.Date;
024: import java.util.List;
025: import java.util.Properties;
026: import java.util.Random;
027:
028: public class LongrunningGCTestApp implements Application {
029:
030: private TCLogger logger = new TCLogger() {
031:
032: PrintStream out = System.out;
033:
034: DateFormat df = DateFormat.getDateTimeInstance();
035:
036: private void println(String header, Object message) {
037: out.println(format(header + message));
038: }
039:
040: private void println(String header, Object message, Throwable t) {
041: out.println(format(header + message, t));
042: }
043:
044: private String format(Object message) {
045: return df.format(new java.util.Date()) + message;
046: }
047:
048: private String format(Object message, Throwable t) {
049: CharArrayWriter chaw = new CharArrayWriter();
050: PrintWriter ps = new PrintWriter(chaw);
051: t.printStackTrace(ps);
052: ps.flush();
053:
054: return format(message + chaw.toString());
055: }
056:
057: public void debug(Object message) {
058: println(" DEBUG ", message);
059: }
060:
061: public void debug(Object message, Throwable t) {
062: println(" DEBUG ", message, t);
063: }
064:
065: public void error(Object message) {
066: println(" ERROR ", message);
067: }
068:
069: public void error(Object message, Throwable t) {
070: println(" ERROR ", message, t);
071: }
072:
073: public void fatal(Object message) {
074: println(" FATAL ", message);
075: }
076:
077: public void fatal(Object message, Throwable t) {
078: println(" FATAL ", message, t);
079: }
080:
081: public void info(Object message) {
082: println(" INFO ", message);
083: }
084:
085: public void info(Object message, Throwable t) {
086: println(" INFO ", message, t);
087: }
088:
089: public void warn(Object message) {
090: println(" WARN ", message);
091: }
092:
093: public void warn(Object message, Throwable t) {
094: println(" WARN ", message, t);
095: }
096:
097: public void log(LogLevel level, Object message) {
098: println(level.toString(), message);
099: }
100:
101: public void log(LogLevel level, Object message, Throwable t) {
102: println(level.toString(), message, t);
103: }
104:
105: public boolean isDebugEnabled() {
106: return true;
107: }
108:
109: public boolean isInfoEnabled() {
110: return true;
111: }
112:
113: public void setAdditivity(boolean additive) {
114: return;
115: }
116:
117: public void setLevel(LogLevel level) {
118: return;
119: }
120:
121: public LogLevel getLevel() {
122: return null;
123: }
124:
125: public String getName() {
126: return getClass().getName();
127: }
128:
129: };
130:
131: private static final long TEST_DURATION = 1000 * 60 * 60 * 24 * 7;
132: private final Date endDate;
133:
134: private String appId;
135: private final StatsListener statsListener;
136: private List list = new ArrayList();
137: private transient List unmanaged = new ArrayList();
138: private transient List agedUnmanaged = new ArrayList();
139: private long loopSleepTime = 0;
140:
141: private boolean useUnmanaged = true;
142: private boolean useAgedUnmanaged = true;
143: private boolean beRandom = true;
144: private boolean doComplex = true;
145:
146: public LongrunningGCTestApp(String appId, ApplicationConfig cfg,
147: ListenerProvider listeners) {
148: this .appId = appId;
149: Properties properties = new Properties();
150: properties.setProperty("sample_name", "100 iterations");
151: this .statsListener = listeners.newStatsListener(properties);
152: if (cfg instanceof LongrunningGCTestAppConfig) {
153: loopSleepTime = ((LongrunningGCTestAppConfig) cfg)
154: .getLoopSleepTime();
155: }
156: endDate = new Date(System.currentTimeMillis() + TEST_DURATION);
157: }
158:
159: public String getApplicationId() {
160: return appId;
161: }
162:
163: public boolean interpretResult(Object result) {
164: return true;
165: }
166:
167: public void run() {
168: println("starting " + getClass());
169: println("Will run until " + endDate);
170: if (doComplex)
171: doComplex();
172: else
173: doSimple();
174: println("All done.");
175: }
176:
177: private boolean shouldContinue() {
178: return System.currentTimeMillis() < endDate.getTime();
179: }
180:
181: private void doSimple() {
182: println("doSimple...");
183: int count = 0;
184: NumberFormat nf = NumberFormat.getInstance();
185: long t0 = System.currentTimeMillis();
186: while (shouldContinue()) {
187:
188: if (count % 200 == 0) {
189: synchronized (list) {
190: println("clearing list (" + list.size() + ")");
191: list.clear();
192: }
193: }
194:
195: Tree tree = new Tree();
196: tree.makeTree(2, 2);
197: synchronized (list) {
198: if (count % 50 == 0) {
199: println("adding to list (" + list.size() + ")");
200: }
201: list.add(tree);
202: }
203:
204: if (count % 100 == 0) {
205: long delta = System.currentTimeMillis() - t0;
206: println("count=" + nf.format(count) + ", time="
207: + nf.format(delta) + " ms.");
208: t0 = System.currentTimeMillis();
209: }
210:
211: count++;
212: }
213: }
214:
215: private void doComplex() {
216: println("doComplex...");
217: println("useUnmanaged : " + useUnmanaged);
218: println("useAgedUnmanaged: " + useAgedUnmanaged);
219: println("beRandom : " + beRandom);
220: println("loopSleepTime : " + loopSleepTime);
221: NumberFormat nf = NumberFormat.getInstance();
222: boolean migratedAgedUnmanaged = false;
223: boolean clearedUnmanagedAndList = false;
224: boolean addedUnmanagedToList = false;
225: Random random = new Random(System.currentTimeMillis()
226: + System.identityHashCode(new Object()));
227: int count = 0;
228: long t0 = System.currentTimeMillis();
229: while (shouldContinue()) {
230: if (count % 100 == 0) {
231: long delta = System.currentTimeMillis() - t0;
232: println("count=" + nf.format(count) + ", time="
233: + nf.format(delta) + " ms.");
234: this .statsListener.sample(delta, "");
235: println("migratedAgedUnmanaged : "
236: + migratedAgedUnmanaged);
237: println("clearedUnmanagedAndList: "
238: + clearedUnmanagedAndList);
239: println("addedUnmanagedToList : "
240: + addedUnmanagedToList);
241:
242: t0 = System.currentTimeMillis();
243: migratedAgedUnmanaged = false;
244: clearedUnmanagedAndList = false;
245: addedUnmanagedToList = false;
246: }
247:
248: if (useAgedUnmanaged && count % random(random, 1001) == 0) {
249: // keep a stash of objects around for a little longer to be added back to
250: // the managed list later.
251: synchronized (agedUnmanaged) {
252: synchronized (list) {
253: println("adding agedUnmanaged ("
254: + agedUnmanaged.size() + ") to list ("
255: + list.size() + ")...");
256: list.addAll(agedUnmanaged);
257: }
258: println("Clearing agedUnmanaged: "
259: + agedUnmanaged.size());
260: agedUnmanaged.clear();
261: synchronized (list) {
262: if (list.size() > 0) {
263: println("adding list element 0 to agedUnmanaged...");
264: agedUnmanaged.add(list.get(0));
265: }
266: }
267: }
268: migratedAgedUnmanaged = true;
269: }
270:
271: if (count % random(random, 500) == 0) {
272: synchronized (list) {
273: println("Clearing unmanaged: " + unmanaged.size());
274: unmanaged.clear();
275: println("Clearing managed: " + list.size());
276: list.clear();
277: }
278: clearedUnmanagedAndList = true;
279: }
280: // move the items from the unmanaged set to the managed list to make sure that
281: // managed objects referenced from an unmanaged graph don't get garbage collected.
282: if (useUnmanaged && count % random(random, 250) == 0) {
283: synchronized (list) {
284: println("Adding elements from unmanaged ("
285: + unmanaged.size() + ") to managed list ("
286: + list.size() + ")...");
287: list.addAll(unmanaged);
288: }
289: addedUnmanagedToList = true;
290: }
291:
292: Tree tree = new Tree();
293: tree.makeTree(2, 2);
294:
295: synchronized (list) {
296: list.add(tree);
297: if (useUnmanaged) {
298: unmanaged.add(tree);
299: }
300: }
301: count++;
302:
303: sleep(loopSleepTime);
304: }
305: }
306:
307: public int random(Random random, int max) {
308: if (!beRandom)
309: return max / 2;
310: int rv;
311: while ((rv = random.nextInt(max)) == 0) {
312: //
313: }
314: return rv;
315: }
316:
317: private void println(Object o) {
318: logger.info("appId[" + appId + "]: " + o);
319: }
320:
321: private void sleep(long ms) {
322: try {
323: Thread.sleep(ms);
324: } catch (InterruptedException e) {
325: throw new AssertionError(e);
326: }
327: }
328:
329: public static void visitL1DSOConfig(ConfigVisitor visitor,
330: DSOClientConfigHelper config) {
331: String testClassName = LongrunningGCTestApp.class.getName();
332: TransparencyClassSpec spec = config
333: .getOrCreateSpec(testClassName);
334: spec.addRoot("list", testClassName + ".list");
335: String methodExpression = "* " + testClassName + ".*(..)";
336: System.err.println("Adding autolock for: " + methodExpression);
337: config.addWriteAutolock(methodExpression);
338:
339: spec.addTransient("unmanaged");
340: spec.addTransient("agedUnmanaged");
341:
342: config.addIncludePattern(Tree.class.getName());
343: config.addExcludePattern(LongrunningGCTestAppConfig.class
344: .getName());
345: config.addExcludePattern(LongrunningGCTestAppConfigObject.class
346: .getName());
347: }
348:
349: public static void visitDSOApplicationConfig(ConfigVisitor visitor,
350: DSOApplicationConfig config) {
351: String classname = LongrunningGCTestApp.class.getName();
352: config.addRoot("LongrunningGCTestAppList", classname + ".list");
353: config.addWriteAutolock("* " + classname + ".*(..)");
354:
355: config.addIncludePattern(LongrunningGCTestApp.class.getName(),
356: true);
357: config.addIncludePattern(Tree.class.getName());
358: }
359:
360: }
|