Maison  >  Questions et réponses  >  le corps du texte

Comment utiliser JDBC en Java pour implémenter des mises à jour continues du serveur de base de données sans augmenter la consommation de RAM

J'ai écrit un jeu de combat en JavaFX, en utilisant JDBC pour mettre à jour les informations dans une base de données MySQL. La plupart des tâches qui obtiennent des informations de base du serveur de base de données fonctionnent correctement si elles ne sont pas répétées de manière continue. Le problème survient lorsque j'ai besoin que le programme mette constamment à jour les informations de l'adversaire, telles que la position, le niveau, les dégâts, etc. dans le jeu. Je dois constamment envoyer des commandes de sélection au serveur, ce qui augmente la RAM utilisée par le thread exécutant ces commandes.

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

J'ai essayé de rechercher quelques méthodes et j'ai trouvé une méthode très utile. Après chaque sélection, je laisse le fil dormir pendant un moment avant de faire une autre sélection. Cette approche améliore considérablement les performances et la consommation de RAM reste stable. Cependant, cette approche n'est pas adaptée aux informations de requête qui doivent être actualisées en permanence, car la courte veille du thread « select » entraînera toujours une consommation élevée de RAM. Existe-t-il un moyen utile de résoudre ce problème et de laisser mon jeu se connecter directement au serveur de base de données sans passer par le serveur de jeu intermédiaire.

P粉323224129P粉323224129428 Il y a quelques jours783

répondre à tous(1)je répondrai

  • P粉136356287

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

    Vous devriez d'abord essayer d'optimiser vos variables.

    Votre fil continue d'utiliser la nouvelle chaîne lors de l'interrogation, alors qu'en fait il ne doit être construit qu'une seule fois. De même, pour votre ResultSet, chaque fois que vous entrez dans une nouvelle boucle, vous utilisez un nouvel emplacement dans la RAM pour stocker un nouvel objet.

    Vous pouvez vérifier cela en ajoutant une sortie de console en dehors de l'objet Java ID :

    System.out.println(resultSet);

    Observez ensuite si les résultats de sortie sont différents à chaque fois.

    Comme ça :

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

    Ensuite, je vous demande d'envisager de modifier votre requête pour sélectionner uniquement les valeurs où xPos/yPos n'est pas égal à "-1", et d'obtenir uniquement les résultats des changements de position réels de l'adversaire, et enfin, peut-être au lieu d'envoyer un "nouveau Position", il suffit d'envoyer deux variables opposéesX et opposéesY, cela évite de stocker cet objet en RAM.

    N'oubliez pas que Java ne nettoie vos objets RAM qu'une fois l'exécution du code terminée (en bref), donc avoir un seul thread qui ne se termine jamais ne déclenchera pas cela.

    répondre
    0
  • Annulerrépondre