Files
jlibcom/unittest/com/jacob/com/ROT3Test.java
clay_shooter 5bcb855846 SF1603631:
concurrent modification of ROT (adding or removing thread tables) causes VM crash.  The simple fix is to sychronize all accessors to the ROT.  Performance impact has not been analyzed
2006-12-08 13:03:55 +00:00

134 lines
4.3 KiB
Java

package com.jacob.com;
/**
* This trys to exercise ROT's garbage collecion
* This is named this way because the build.xml
* ignores files ending in Test when building the binary zip file
*
* This will eventually be changed to a unit test.
*
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
*/
public class ROT3Test
{
public static void main(String args[]) throws Exception
{
ROT3TestThread threads[] = new ROT3TestThread[4];
for (int i = 0; i < threads.length; i++)
{
threads[i] = new ROT3TestThread("thread-" + i, 3000+i*10);
}
for (int i = 0; i < threads.length; i++)
{
threads[i].start();
}
}
}
/**
* This wil try and exercise the thread support in the ROT
**/
class ROT3TestThread extends Thread
{
private java.util.List variansCreatedInThisThread;
private int initialRunSize = 0;
/**
* @param arg0
*/
public ROT3TestThread(String arg0, int iStartCount)
{
super(arg0);
initialRunSize = iStartCount;
}
/**
* A semi-complexe serie of steps to put the ROT under stress. 1) discard
* half the objects we've created 2) if size is greater than 1 but not a
* even number, add 1 new object 3) stop when size is 1.
*
* @see java.lang.Runnable#run()
*/
public void run()
{
// something that keeps object references around
// so the gc can't collect them
// we need to create these in the thread so they end up in the right ROT table
variansCreatedInThisThread = new java.util.ArrayList(initialRunSize);
for (int i = 0; i < initialRunSize; i++)
{
// create the object
Variant aNewVariant = new Variant(getName() + "_" + i);
// create a hard reference to it
variansCreatedInThisThread.add(aNewVariant);
}
while (variansCreatedInThisThread.size() > 1)
{
String message = "";
message = getName()+" Workingset=" +variansCreatedInThisThread.size()
+" ROT threadObject hashCode: "+ROT.getThreadObjects(true).hashCode();
message += " size before mods and gc "+ROT.getThreadObjects(true).size()+")";
// If there are more than 10 objects in our cache then add 1/4 of that again
if (variansCreatedInThisThread.size() > 10)
{
message+= " (adding) ";
// add an additional 1/4 of our current number
for ( int i = 0 ; i < variansCreatedInThisThread.size()/4 ; i++){
// add a new object
Variant aNewVariant = new Variant(getName() + "_*" + variansCreatedInThisThread.size());
variansCreatedInThisThread.add(aNewVariant);
}
}
// now iterate across 1/2 the objects in our list
message += " (removing) ";
for (int i = variansCreatedInThisThread.size(); i > 0; i--)
{
// removing every other one?
if (i % 2 == 0)
{
// remove the reference so gc can get it
if (!ROT.USE_AUTOMATIC_GARBAGE_COLLECTION){
// uses deprecated API to set up a special situation
// because this is an ROT test
ROT.removeObject((JacobObject)variansCreatedInThisThread.get(i-1));
}
variansCreatedInThisThread.remove(i-1);
}
}
message += " (after mods "+ROT.getThreadObjects(true).size()+")";
// comm
if (!ROT.USE_AUTOMATIC_GARBAGE_COLLECTION){
ROT.clearObjects();
}
System.gc();
try {
// vain attempt at letting the gc run
Thread.sleep(200);
} catch (InterruptedException ie){
}
message += " (after gc "+ROT.getThreadObjects(true).size()+")";
message += " Should see GC if debug turned on...";
System.out.println(message);
}
}
/**
* Another test would be to overide this to always return the same name.
* That would really screw the ROT!
*
* @see java.lang.Object#toString()
*/
public String toString()
{
return super.toString();
}
}