Java中使用JDBC實作資料庫伺服器的持續更新,同時保持RAM消耗不增加的方法
P粉323224129
P粉323224129 2023-09-07 20:10:29

我在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粉323224129
P粉323224129

全部回覆(1)
P粉136356287

你應該先嘗試優化你的變數。

你的執行緒在查詢時一直使用新的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物件(簡而言之),所以擁有一個永不結束的單一執行緒不會觸發這種情況。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!