Name: boT120536 Date: 01/09/2001
[cporter@src]$ java -server -version
java version "1.3.0_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0_01)
Java HotSpot(TM) Server VM (build 1.3.0_01, mixed mode)
1) Run an RMI server application that maintains MANY objects, a fullGC is run
every minute, thereby neutralizing all advantges of the generational garbage
collector. Run the following example and see full GC hits of 4-6 seconds every
minute, even though NO objects are being created or destroyed. In our much
larger real-world code we get GC hits of up to TWENTY SECONDS PER MINUTE, with
NO object creation.
In sun/rmi/transport/ObjectTable.java , there is a call to GC.requestLatency
(gcInterval) setting a default period for a forced GC to 60 seconds. If
successful operation of RMI depends on this foced GC, which makes the
generational garbage collector worthless, RMI is itself useless for large
servers.
SAMPLE CODE
break up the following text into files
####################################### is a file delimeter in this message
add . to you classpath
run the script do.sh
after aprox ten minutes on a 512 MB Linux box the program will emit a line
saying 1000000 objects added to hashtable in <n> seconds. After that there is
no activity in the RMI server. However, every minute a full GC will run for 4
to 6 seconds, collecting NO garbage
####################################################
# do.sh
#compile
javac TestHashServer.java ITestHash.java
rmic TestHashServer
#register the server ( java.policy below )
rmiregistry -J-Xmx100M -J-Djava.security.policy=./java.policy &
#run
java -server -verbose:gc -XX:NewSize=1M -XX:MaxNewSize=32M -Xms400M -Xmx500M
TestHashServer &
#################################################################
// ITestHash.java
import java.rmi.Remote;
import java.rmi.RemoteException;
/**
*/
public interface ITestHash
extends Remote {
public String getString(String key)
throws RemoteException ;
public void addString(String key,
String val)
throws RemoteException;
public void removeString(String key)
throws RemoteException;
}
#######################################################################
//TestHashServer.java
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;
import java.util.*;
public class TestHashServer
extends UnicastRemoteObject
implements ITestHash {
/**
* the contained data structure that the RmiServer provides
* controlled access.
*/
private Hashtable hash;
/**
* the ctor does nothing except pass in the service name
* (i.e. the name by which it is known to the rmiregistry)
* to the parent class.
*/
public TestHashServer(String serviceName)
throws RemoteException {
hash = new Hashtable();
}
/**
* a wrapper around the hashtable's method.
*/
public String getString(String key)
throws RemoteException {
return (String )hash.get(key);
}
/**
* another wrapper, this time around put()
*/
public void addString(String key,
String val)
throws RemoteException {
hash.put(key,val);
}
/**
* another wrapper, this time around remove()
*/
public void removeString(String key) {
hash.remove(key);
}
/**
* public gettor for constant service name.
* this is the JavaPope(tm) approved method
* of getting constants.
*/
public static String getTestServiceName() {
return "testHashService";
}
public void register()
throws RemoteException, AlreadyBoundException {
String serviceName = getTestServiceName();
// register with registry
LocateRegistry.getRegistry().bind(serviceName, this);
System.out.println("RmiServer "
+ serviceName
+ " registered");
}
/**
*/
public static void main(String[] args)
throws RemoteException, NotBoundException,
java.net.MalformedURLException {
try{
// crate the server object
TestHashServer server = new TestHashServer
(getTestServiceName());
// register with RMI
server.register();
ITestHash server2 = (ITestHash )Naming.lookup
(getTestServiceName());
int count = 1000000;
int stringSize = 50;
long startTime = System.currentTimeMillis();
for( int i = 0; i < count; i++){
StringBuffer b = new StringBuffer(stringSize);
for( int j = 0; j < stringSize; j++){
b.append( j);
}
String s = b.toString();
server2.addString( new Integer(i).toString(), s );
}
long time = System.currentTimeMillis() - startTime;
System.out.println( "hash filled with "+ count + " int
arrays in " + time + "ms");
Object semaphore = new Object();
while( true )
{
synchronized( semaphore ){
semaphore.wait( 60 * 1000 );
}
System.out.print(" . ");
}
}
catch( Exception e){
e.printStackTrace();
}
}
}
###########################################################################
//java.policy
grant {
permission java.security.AllPermission;
};
#########################################################################
(Review ID: 114860)
======================================================================