Solved Memory Issues

Discussion in 'BungeeCord Plugin Development' started by DziNeIT, Jan 21, 2020.

  1. Currently writing a BungeeCord plugin (I'm experienced with Java and Bukkit/Spigot/Minecraft code, less so with Bungee) and running into some issues where the test server is running out of memory.

    All the plugin does is query a MySQL database (a simple select query on a table with two columns and only a handful of rows), but it does do it quite regularly (the task is set in Bungee to execute every 200ms).

    The task works as follows (note that code is minimal and slightly transformed to pseudocode in some places):

    In onEnable():
    Code (Java):
    getProxy().getScheduler().schedule(this, new Task(this), 200L, 200L, TimeUnit.MILLISECONDS);
    Task run():
    Code (Java):
    plugin.getProxy().getScheduler().runAsync(plugin, () -> {
        Connection con = plugin.getDatabase().getConnection();
        if (con == null) return;

        try {
                PreparedStatement statement = con.prepareStatement("SELECT * FROM table");
                ResultSet resultSet = statement.executeQuery();

                while (resultSet.next()) {
                    k = resultSet.get___("****");
                    v = resultSet.get___("****");
                    map.put(k, v);
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
    }
    I gather that the problem could almost certainly be solved by simply reducing the frequency of the task, and I have another solution in mind which may allow me to solve it without doing that, but I'm curious for the perspectives of Bungee-experienced developers who might be able to tell me exactly what is going wrong and what the transmission mechanism is for the server to be running out of memory here.
     
    #1 DziNeIT, Jan 21, 2020
    Last edited: Jan 21, 2020
  2. Bungee scheduler is all async so it is redundant to call the scheduler here:

    Perhaps this is memory problem.
     
    • Informative Informative x 1
  3. MiniDigger

    Supporter

    I bet you are leaking connection to the database.
    what does your getConnection method do? do you use a connection pool?
     
  4. It's a single persistent connection (connects on plugin enable, disconnects on disable) - I would use pooling if the database was expected to be accessed by multiple threads but in this case the task I describe in my post is the only instance of the database ever being accessed - should I still be using pooling in this case?
     
  5. Thanks, was not aware of that.
     
  6. MiniDigger

    Supporter

    Meh, I guess that should be fine.

    Next guess, your map becomes big. What kind of map is it. What is your key? Does that implement the hashcode equals contract?
     
  7. Keys and values are in-built Java classes (primitives, namely) and it's a standard HashMap. The number of keys is consistently one in the test case in which I'm experiencing this issue, as the code shown is the only time it is updated, and the database only has one row (I have verified this by querying the database separately).
     
  8. MiniDigger

    Supporter

    mmmh, ok.
    I guess a result set can leak stuff too, try closing that once you are done reading.
    did you address what ivan said?
     
    • Informative Informative x 1
  9. Ah great point, I'll use try-with-resources for both the PreparedStatement and ResultSet. I'd forgotten about closing them as it's been a while since I did SQL in Java. I've also removed the explicit async call as Ivan suggested. Will test again and mark as solved if it's fixed, otherwise I'll get back to you.