Domanda

I have the following daemon that runs in a loop:

public class MyDaemon implements Daemon {

    private Thread myThread;
    private boolean stopped = false;

    private DatagramChannel channel;

    @Override
    public void init(DaemonContext daemonContext) throws DaemonInitException,
            Exception {

        myThread = new Thread() {

            @Override
            public synchronized void start() {
                MyDaemon.this.stopped = false;
                super.start();
            }

            @Override
            public void run() {
                            ByteBuffer buf = ByteBuffer.allocate(100);

                while (!stopped) {

                    try {
                        channel.receive(buf);
                        String payload = buf;
                        ArrayList<Element> elements = buf.elements();

                        Message message = new Message();
                        message.setPayload();
                        message.setElements(elements);

                        DataManager controller = null;
                        try {
                            dm = new DataManager();
                        } catch (ClassNotFoundException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (SQLException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        dm.saveMessage(message);
                        Thread.sleep(100);
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                }
            }
        };
    }

    public static void main(String args[]) {

    }

    @Override
    public void start() throws Exception {

        channel = DatagramChannel.open();
        channel.socket().bind(new InetSocketAddress(1400));
        channel.configureBlocking(false);
        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;
    }
}

My data manager class simply looks like the following:

public class DataManager {

    private static String insert = "insert into mytable "
                        + “(payload, elementId, time)”
                        + "values (?,?,?);”;

    public Connection instantiateConnection() throws ClassNotFoundException,
            SQLException {



        Connection connection = DriverManager.getConnection("jdbc connection info”);

        return connection;
    }



    public void saveMessage(Message message) {
        try {
            Connection connection = this.instantiateConnection();

                connection.setAutoCommit(false);
                PreparedStatement ps = connection.prepareStatement(insert);

                for (Element element : message.getElements()) {
                    Timestamp time = new Timestamp(date.getTime());
                    ps.setString(1, message.getPayload());
                    ps.setString(2, element.getId());
                           ps.setTimestamp(3, time);
                    ps.addBatch();
                }
                ps.executeBatch();
                connection.commit();
                ps.close();
                connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }

}

Lastly, this is the ssh file that runs my daemon:

#!/bin/sh

# Setup variables EXEC=/usr/bin/jsvc



PID=/tmp/mydaemon.pid JAVA_HOME=/usr/lib/jvm/jre CLASS_PATH="/home/ec2-user/commons-daemon-1.0.15.jar”:”/MyDaemon.jar" CLASS=MyDaemon USER=ec2-user LOG_OUT=/tmp/mydaemon.out LOG_ERR=/mydaemon.err

do_exec() {
    $EXEC -home "$JAVA_HOME" -cp $CLASS_PATH -user $USER -outfile $LOG_OUT -errfile $LOG_ERR -pidfile $PID $1 $CLASS }

case "$1" in
    start)
        do_exec
            ;;
    stop)
        do_exec "-stop"
            ;;
    restart)
        if [ -f "$PID" ]; then
            do_exec "-stop"
            do_exec
        else
            echo "service not running, will do nothing"
            exit 1
        fi
            ;;
    *)
            echo "usage: daemon {start|stop|restart}" >&2
            exit 3
            ;; esac

This is a complete set of the code. Please help!

When this runs, the memory slowly grows until I get an out of memory exception.

Does anyone know what is leaking?

È stato utile?

Soluzione 2

@Rembo Thanks a million! You were right on.

I added c3p0 connection pooling and I have been garbage collecting like a bum in january ever since.

Altri suggerimenti

You are allocating the buffer inside each iteration of while loop. This is redundant and you dont need it as you are clearing the buffer at the end of the loop. Do this :

  ByteBuffer buf = ByteBuffer.allocate(100); 
  while(!stopped)
  {
     // do something

      buf.clear();
 }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top