如何在不增加RAM消耗量的情况下用Java中的JDBC不断更新数据库服务器?

siv3szwd  于 2023-06-04  发布在  Java
关注(0)|答案(1)|浏览(141)

我用JavaFX写了一个格斗游戏,使用JDBC将信息更新到MySQL数据库。大多数从数据库服务器获取基本信息的任务如果不连续重复,就能正常工作。问题发生时,我需要为程序不断更新信息,从对手,如位置,水平,损害在游戏中。我必须不断地向服务器发送select命令,这会增加运行这些命令的线程所使用的RAM。

void startUpdatingOpponentInfo() {
    Thread thread = new Thread(() -> {
        while (matchID != -1) {
            String query = String.format("select * from matchDetails where matchID = %d and userID = %d", matchID, opponentID);
            try {
                ResultSet resultSet = sqlConnection.getDataQuery(query);
                while (resultSet.next()) {
                    double opponentX = resultSet.getDouble("xPos");
                    double opponentY = resultSet.getDouble("YPos");
                    if (opponentX != -1 && opponentY != -1)
                        opponent.move(canvas, new Position(opponentX, opponentY));
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    });
}

  public ResultSet getDataQuery(String query) {
    Statement statement;
    ResultSet resultSet = null;
    try {
        statement = connection.createStatement();
        resultSet = statement.executeQuery(query);
    } catch (SQLException e) {
        System.out.println(query);
        e.printStackTrace();
    }
    return resultSet;
}

我试着搜索了几种方法,找到了一种非常有用的方法。在每次选择之后,我将让该线程休眠一段时间,然后再次选择。这种方式显著提高了性能,RAM消耗量保持稳定。但是,它不适合查询总是需要刷新的信息,因为“选择”线程的短暂睡眠仍然会消耗很高的RAM。对于这个问题,我允许我的游戏直接连接到数据库服务器而不通过中间游戏服务器,有没有什么有用的方法。

zc0qhyus

zc0qhyus1#

你应该首先尝试优化你的变量。
您的线程一直使用new String进行查询,而它似乎只能构建一次。对于你的ResultSet也是一样,每次你运行到一个新的循环中,你将在RAM中为一个新的对象使用一个新的位置。
你可以通过在Java ID对象中添加一个控制台来检查这一点:

System.out.println(resultSet);

每次都不一样
就像这样:

Thread thread = new Thread(() -> {

        ResultSet resultSet;
        final String query = String.format("select * from matchDetails where matchID = %d and userID = %d", matchID, opponentID);

        while (matchID != -1) {
            try {
                resultSet = sqlConnection.getDataQuery(query);

然后我让你考虑改变你的查询,只选择xPos/yPos不等于“-1”,并得到一个结果,只有一个真实的的对手的位置变化,最后,也许不发送一个“新的位置”,但只有2个变量opponentX和Y,这将阻止你的RAM存储这个对象。
别忘了Java只会在代码执行完成后清理RAM对象(简短的版本),所以有一个永不结束的线程不会进入这种情况。

相关问题