Java 双端队列/准备语句内存泄漏

发布于 2024-08-07 15:44:55 字数 1875 浏览 1 评论 0原文

以下代码片段之一会产生内存泄漏,您知道是哪一部分吗?

1)

private Deque<Snapshot> snapshots = new LinkedList<Snapshot>();

Iterator<Snapshot> i = world.getSnapshots().descendingIterator();
    while (i.hasNext()) {
        Snapshot s = i.next();
        if (curTime - s.getTimestamp() > 60000) {
            i.remove();
        } else {
            break;
        }
    }

2)

public static void initilizePreparedStatements() {
        try {
            insertNewReportRow = Instance.getWorld().getDB().getConnection().prepareStatement("INSERT INTO `rsca2_reports` (`from`, `about`, `time`, `reason`, `snapshot_from`,`snapshot_about`,`chatlogs`, `from_x`, `from_y`, `about_x`, `about_y`) VALUES(?,?,?,?,?,?,?,?,?,?,?)");
        } catch (SQLException e) {
            e.printStackTrace();
            Logger.error(e);
        }
    }
    public synchronized static void submitReport() {
        /*removed*/
            try {
                    insertNewReportRow.setLong(1, from);
                    insertNewReportRow.setLong(2, about); 
                    insertNewReportRow.setLong(3, time); 
                    insertNewReportRow.setInt(4, reason);
                    insertNewReportRow.setString(5, snapshot_from);
                    insertNewReportRow.setString(6, snapshot_about);
                    insertNewReportRow.setString(7, chatlog);
                    insertNewReportRow.setInt(8, f.getX());
                    insertNewReportRow.setInt(9, f.getY());
                    insertNewReportRow.setInt(10, a.getX());
                    insertNewReportRow.setInt(11, a.getY());
                    insertNewReportRow.executeUpdate();
                } catch (SQLException e) {
                    e.printStackTrace();
                    Logger.error(e);
                } 
            }

One of the following pieces of code generates a memory leak, any idea which part?

1)

private Deque<Snapshot> snapshots = new LinkedList<Snapshot>();

Iterator<Snapshot> i = world.getSnapshots().descendingIterator();
    while (i.hasNext()) {
        Snapshot s = i.next();
        if (curTime - s.getTimestamp() > 60000) {
            i.remove();
        } else {
            break;
        }
    }

2)

public static void initilizePreparedStatements() {
        try {
            insertNewReportRow = Instance.getWorld().getDB().getConnection().prepareStatement("INSERT INTO `rsca2_reports` (`from`, `about`, `time`, `reason`, `snapshot_from`,`snapshot_about`,`chatlogs`, `from_x`, `from_y`, `about_x`, `about_y`) VALUES(?,?,?,?,?,?,?,?,?,?,?)");
        } catch (SQLException e) {
            e.printStackTrace();
            Logger.error(e);
        }
    }
    public synchronized static void submitReport() {
        /*removed*/
            try {
                    insertNewReportRow.setLong(1, from);
                    insertNewReportRow.setLong(2, about); 
                    insertNewReportRow.setLong(3, time); 
                    insertNewReportRow.setInt(4, reason);
                    insertNewReportRow.setString(5, snapshot_from);
                    insertNewReportRow.setString(6, snapshot_about);
                    insertNewReportRow.setString(7, chatlog);
                    insertNewReportRow.setInt(8, f.getX());
                    insertNewReportRow.setInt(9, f.getY());
                    insertNewReportRow.setInt(10, a.getX());
                    insertNewReportRow.setInt(11, a.getY());
                    insertNewReportRow.executeUpdate();
                } catch (SQLException e) {
                    e.printStackTrace();
                    Logger.error(e);
                } 
            }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

流绪微梦 2024-08-14 15:44:55

我的猜测是,您可以在 Instance.getWorld().getDB().getConnection() 中获取连接,并且仅存储对其创建的准备好的语句的引用。
这意味着当代码使用准备好的语句完成时,您不会释放连接,并且(假设它来自连接池)连接池不会回收连接,但会在其映射中保留对它的引用。

My guess would be it's Instance.getWorld().getDB().getConnection() where you get a connection and only store a reference to the prepared statement it creates.
This means you do not free the connection when your code is done with the prepared statement and the (assuming it comes from a connection pool) connection pool does not recycle the connection, but it will keep a reference to it in its maps.

痴情 2024-08-14 15:44:55

根据实现的不同,迭代器中断可能会导致迭代器无法完成自身并阻止其自身释放绑定资源,从而导致内存泄漏。也有可能您从不清理双端队列,这会导致大小随着时间的推移而线性增长。

Depending on implementation, breaking from iterator may cause the iterator to not complete itself and prevent itself from freeing tied resources and thus causing a memory leak. It's also possible you never clean your Deque either which causes linear growth in size over time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文