Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danielmitterdorfer/2bae1b061b424d10b1be5d7323b59a9a to your computer and use it in GitHub Desktop.
Save danielmitterdorfer/2bae1b061b424d10b1be5d7323b59a9a to your computer and use it in GitHub Desktop.
GC benchmark producing a mix of lifetime=0 and lifetime>0 objects which are kept in randomly updated lists
package de.am.gc.benchmarks;
import java.util.ArrayList;
import java.util.List;
/**
* GC benchmark producing a mix of lifetime=0 and lifetime>0 objects which are kept in randomly updated lists.
*
* @author jsound
*/
public class MixedRandomList {
private static final int DEFAULT_NUMBEROFTHREADS=1;
// object size in bytes
private static final int DEFAULT_OBJECTSIZE=100;
private static int numberOfThreads=DEFAULT_NUMBEROFTHREADS;
private static int objectSize=DEFAULT_OBJECTSIZE;
// Number of objects to fill about half of the available memory with live objects
// The result of this calculation is not a constant with different garbage collectors.
// Therefore, it is preferable to set this value as an explicit parameter to the benchmark.
// Explicit setting is required if objectsize is different from default
private static long numLive = (Runtime.getRuntime().maxMemory()/objectSize/5);
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
if( args.length>0 ) {
// first, optional argument is the size of the objects
objectSize = Integer.parseInt(args[0]);
// second, optional argument is the number of threads
if( args.length>1 ) {
numberOfThreads = Integer.parseInt(args[1]);
// third, optional argument is the number of live objects
if( args.length>2 ) {
numLive = Long.parseLong(args[2]);
}
}
}
for( int i=0; i<numberOfThreads; i++ ) {
// run several GarbageProducer threads, each with its own mix of lifetime=0 and higher lifetime objects
new Thread(new GarbageProducer((int)Math.pow(50.0,(double)(i+1)), numLive/numberOfThreads)).start();
}
try {
Thread.sleep(1200000);
} catch( InterruptedException iexc) {
iexc.printStackTrace();
}
System.exit(0);
}
/**
* Create a character array of a given length
* @param length
* @return the character array
*/
private static char[] getCharArray(int length) {
char[] retVal = new char[length];
for(int i=0; i<length; i++ ) {
retVal[i] = 'a';
}
return retVal;
}
/**
* A garbage producer implementation
*/
public static class GarbageProducer implements Runnable {
// the fraction of newly created objects that do not become garbage immediately but are stored in the liveList
int fractionLive;
// the size of the liveList
long myNumLive;
/**
* Each GarbageProducer creates objects that become garbage immediately (lifetime=0) and
* objects that become garbage only after a lifetime>0 which is distributed about an average lifetime.
* This average lifetime is a function of fractionLive and numLive
*
* @param fractionLive
* @param numLive
*/
public GarbageProducer(int fractionLive, long numLive) {
this.fractionLive = fractionLive;
this.myNumLive = numLive;
}
@Override
public void run() {
int osize = objectSize;
char[] chars = getCharArray(objectSize);
List<String> liveList = new ArrayList<String>((int)myNumLive);
// initially, the lifeList is filled
for(int i=0; i<myNumLive; i++) {
liveList.add(new String(chars));
}
while(true) {
// create the majority of objects as garbage
for(int i=0; i<fractionLive; i++) {
String garbageObject = new String(chars);
}
// keep the fraction of objects live by placing them in the list (at a random index)
int index = (int)(Math.random()*myNumLive);
liveList.set(index, new String(chars));
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment