I have the following java daemon which implements the apache commons daemon. It is running on an ec2 amazon ami with icedtea6.
public class MainDaemon implements Daemon {
private Thread myThread;
private boolean stopped = false;
@Override
public void init(DaemonContext daemonContext) throws DaemonInitException, Exception {
String[] args = daemonContext.getArguments();
myThread = new Thread(){
@Override
public synchronized void start() {
MainDaemon.this.stopped = false;
super.start();
}
@Override
public void run() {
while(!stopped){
byte[] rcvMsg = incomingBinaryMessage;
MessageCreator tmc = new MessageCreator();
Message message = null;
try {
message = tmc.createMessage(rcvMsg);
System.out.println(message);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
}
@Override
public void start() throws Exception {
myThread.start();
}
@Override
public void stop() throws Exception {
stopped = true;
try{
myThread.join(1000);
}catch(InterruptedException e){
System.err.println(e.getMessage());
throw e;
}
}
@Override
public void destroy() {
myThread = null;
}
}
The MessageCreator just reads the data in from a byte array input stream, places the output into an object and returns it:
public Message createMessage(byte[] rcvMsg) {
Message message = new Message();
ByteArrayInputStream bais = new ByteArrayInputStream(rcvMsg);
DataInput input = new DataInputStream(bais);
try {
int MsgType = 0;
MsgType = input.readShort();
message.setType(MsgType);
return message;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
The message is a pojo:
public class Message {
private int type;
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
}
As the daemon runs, the memory slowly creeps up until I get an out of memory exception.
I know this is happening in the messageconstructor class because when I comment out the call to this method, the memory stays constant for the entire session the daemon runs.
I get the following error after a few hours:
Exception in thread "Thread-0" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOfRange(Arrays.java:3221)
at java.lang.String.<init>(String.java:233)
at java.lang.StringBuilder.toString(StringBuilder.java:447)
at sun.net.www.protocol.jar.Handler.parseContextSpec(Handler.java:138)
at sun.net.www.protocol.jar.Handler.parseURL(Handler.java:84)
at java.net.URL.<init>(URL.java:614)
at java.net.URL.<init>(URL.java:482)
at sun.misc.URLClassPath$JarLoader.checkResource(URLClassPath.java:688)
at sun.misc.URLClassPath$JarLoader.getResource(URLClassPath.java:773)
at sun.misc.URLClassPath.getResource(URLClassPath.java:185)
at java.net.URLClassLoader$1.run(URLClassLoader.java:209)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:435)
at com.mysql.jdbc.PreparedStatement.getInstance(PreparedStatement.java:872)
at com.mysql.jdbc.ConnectionImpl.clientPrepareStatement(ConnectionImpl.java:1490)
at com.mysql.jdbc.ConnectionImpl.prepareStatement(ConnectionImpl.java:4253)
at com.mysql.jdbc.ConnectionImpl.prepareStatement(ConnectionImpl.java:4152)
at MySQLConnect.insertTagEncounters(MySQLConnect.java:89)
at DataControllerImp.saveMessage(DataControllerImp.java:35)
at MainDaemon$1.run(MainDaemon.java:74)
What am I doing wrong in creating the MessageConstructor in the run loop that is leaking memory?