簡體   English   中英

簡單的java循環寫入數據庫會導致內存不足異常

[英]simple java loop writing to database causes out of memory exception

我有一個循環運行的守護進程:

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;
    }
}

我的數據管理器類看起來如下所示:

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();
        }

    }

}

最后,這是運行我的守護進程的ssh文件:

#!/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

這是一套完整的代碼。 請幫忙!

當它運行時,內存會慢慢增長,直到出現內存不足異常。

有誰知道什么是泄漏?

您在while循環的每次迭代中分配緩沖區。 這是多余的,你不需要它,因為你在循環結束時清除緩沖區。 做這個 :

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

      buf.clear();
 }

@Rembo萬分感謝! 你是對的。

我添加了c3p0連接池,從那時起我就像垃圾收集一樣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM