General Do-nots to prevent memory/resource leaks?

Discussion in 'Plugin Development' started by Boomer, Apr 18, 2014.

Thread Status:
Not open for further replies.
  1. Offline

    Boomer

    I've been going through all of my plugins and finding that some of my really older ones I've made still have Maps and Sets with Player objects in them.

    I learned long after making those of course, that using the Player object in a set/map (even if I did attempt to remove them when logging out) can cause leaks and issues if it remains in the set and they player logs out/in again, the object is different, the old object reference never gets removed, and map chunks etc for that former player object remain in memory, etc, etc...

    ---

    Are there any lists available for other such "Gotcha's" of things that we should watch out for doing that can lead to memory /resource locks/leaks over time similarly, specific to Bukkit.

    There must be several other common pitfalls like this one, specific to Bukkit concepts, rather than generic java issues. A generic java issue would prob describe the Player-object-Set-map-chunks via some elaborate interface/inheritable/non-newtonian/quasidimensional description that those who know how all the bukkit things are tied together, know thats one of the things meeting the description...

    For those of us without the ability to know "Never refer to an inherited object in a contract with an asynch object that isn't inheriting the generic base class without a constructor that has a final reference to a closed set method iterator" etc etc applies to the relationship between a player inventory and a chunk... What are the often-repeated problems that convergent-coder evolution tends to produce that should be nipped to prevent resource leaks?
     
  2. Offline

    Glumpz

  3. Offline

    Boomer

    Thanks, but it doesn't seem to be getting any suggestions or references gathered ;)
     
  4. Offline

    Europia79

    This is really hard to read. Can you elaborate ? Or provide a small code sample to demonstrate this ?

    ^^ Okay, kinda got this first part, except the contract (never seen it in action). Maybe you're referring to an interface ?

    Exception to the rule ? (me trying to decipher)
    ^^ So if the asynch object is inheriting the generic base class OF the object you're referencing, then the reference is okay ?

    ^^ So, if the asynch object is NOT inheriting the generic base class OF the object you're referencing, then the reference is not okay ?

    proper approach ? (me trying to decipher)
    ^^ final reference to what ? ...an iterator object ?

    Anyways, if i run into any code leak problems in my code, i'll let you know what to avoid. Thanks!
     
  5. Offline

    xTrollxDudex

    Boomer
    Any type of reference to the Player object will cause memory leaks if not GCd. That includes strong refs, access to finalized Player object, any type of Collection or array including Queues, Lists, Maps, and Sets, ect...

    When in doubt, if you hold internal objects or Bukkit references that should be handled when Class is unloaded, remove it when it does so. WeakReference and WeakHashMap MIGHT work, but a forewarning, lingering references CAN still cause memory leaks. It is best to explicitly remove it.

    Otherwise, use String or some other Java object to reference Bukkit objects, int arrays for coordinate reference to Chunk, UUIDs, ect...
     
  6. Offline

    Boomer

    if I have a method x() that makes Block b = something.something.something.getBlock() in order to manipulate that block, and then just terminate the method, object b eventually gets cleaned up by the system as its scope was limited to the instance called. In other languages, these objects needed to be set to nothing / null at the end of the method to avoid leaking. I have never ever seen any plugin code that does this with anything in any methods, so is java that much better at explicitly knowing to null the object when its scope is done, or, does that happen only at cleanup.
    Would there be benfits to setting things null - free up memory much sooner without waiting for the gc to go in and say 'those 1200 old block b references stacked together - all can be wiped now' ? Trying to picture the "remove it when it does so" remark in this context...
    Its okay to pass a player object from one method to another, if the second is a function that instantly returns something for the first method to use? Or is it still preferrable there to pass .getName() / uuid , and then in the second method, get the player object from there? If the second method exists, acts, then ends all within the timeframe of the first method existing, and doesn't hold onto a persistant thing this is okay to pass player objects? In this scenario, should the player objects be nulled?
    How significant do the differences become if method a() calling b(arg) for player object to use, vs string/uuid to reacquire a player object are performed 5 tiems per minute? 50 times per minute? 500 times per minute? 2000 times per minute?
     
  7. Offline

    xize

    there are many things which could let to resource leaks.

    for example when a player joins and leaves even if you store things as String always clear them when they quit including on kick in case of banning whatsoever.

    but there are also problems with using static sometimes things will become resistant a good example which I suspect which could make a memory leak is this:

    for example you put this inside the superclass aka your main:
    Code:
    private final static HashMap<String, String> hash = new HashMap<String, String>();
    
    because you create everytime a new HashMap on restart there is a chance the old singleton has a other memory decleration in the jvm, which means everytime a new singleton could be created which will hang for a time, since a singleton isn't linked to any class it could happen, but I can't be sure with this though.

    how to fix this(which I think but I can be totally wrong here):
    Code:
    private final static HashMap<String, String> hash;
     
    public void onEnable() {
        //in case this won't work remove final.
        this.hash = new HashMap<String, String>();
    }
    
    about the HashMaps I need some more feedback I can be wrong/mistated there, but definetly don't use static on a large scale I restrict it myself to do it only when I'm sure the objects are immutable and cannot be changed internally and only when its needed.
     
Thread Status:
Not open for further replies.

Share This Page