首页  >  问答  >  正文

Java中使用JDBC实现数据库服务器的持续更新,同时保持RAM消耗不增加的方法

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

我尝试搜索了一些方法,找到了一个非常有用的方法。在每个select之后,我会让线程休眠一段时间,然后再进行select。这种方式显着提高了性能,RAM的消耗量保持稳定。然而,对于需要始终刷新的查询信息来说,这种方法并不适用,因为“select”线程的短暂休眠仍然会导致RAM消耗较高。是否有任何有用的方法解决这个问题,让我的游戏直接连接到数据库服务器,而不经过中间游戏服务器。

P粉323224129P粉323224129408 天前759

全部回复(1)我来回复

  • P粉136356287

    P粉1363562872023-09-08 16:23:50

    你应该首先尝试优化你的变量。

    你的线程在查询时一直使用新的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"的值,并且只获取真正的对手位置变化的结果,最后,也许不发送一个"new Position",而只发送两个变量opponentX和opponentY,这样可以避免将这个对象存储在RAM中。

    不要忘记,Java只会在代码执行完成后清理你的RAM对象(简而言之),所以拥有一个永不结束的单一线程不会触发这种情况。

    回复
    0
  • 取消回复