AFK Kicker Memory consumption

Discussion in 'Plugin Development' started by s0undx, Feb 11, 2013.

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

    s0undx

    I have an afk system with 2 files, AFK.java
    Code:
    public class AFK {
        public String PlayerName;
        public int LastAction;
     
        public AFK(Player p){
            this.PlayerName = p.getName();
            this.LastAction = 0;
        }
     
        public void AddSec(){
            this.LastAction += 1;
        }
    }
    , and AFKManager.java
    Code:
    public class AFKManager {
        public static List<AFK> afks = new ArrayList<AFK>();
     
        public static void InitObject(Player p){
            afks.add(new AFK(p));
        }
     
        public static void DisposeObject(Player p){
            AFK r = null;
         
            for(AFK a : afks){
                if(a.PlayerName.equalsIgnoreCase(p.getName())){
                    r = a;
                }
            }
         
            if(r != null)
                afks.remove(r);
        }
     
        public static void Refresh(Player p){
            for(AFK a : afks){
                if(a.PlayerName.equalsIgnoreCase(p.getName())){
                    a.LastAction = 0;
                }
            }
        }
    }
    and a scheduled task:
    Code:
        @SuppressWarnings("deprecation")
        public void TickAFKLoop(){
            int TaskID = Bukkit.getServer().getScheduler().scheduleAsyncRepeatingTask(this, new Runnable() {
                @Override
                public void run() {
                    List<Player> will_kick = new ArrayList<Player>();
                   
                    for(AFK a : AFKManager.afks){
                        a.AddSec();
                       
                        Player p = Bukkit.getPlayer(a.PlayerName);
                        if(p != null && !p.isOp()){
                            int LastAc = a.LastAction;
                            PVPMatch m = MapManager.GetMatchForPlayer(p);
                            int needed = 0;
                           
                            if(m != null){
                                needed = 18;
                            }else{
                                needed = 60;
                            }
                           
                            if(LastAc >= needed){
                                will_kick.add(p);
                            }
                        }
                    }
                   
                    for(Player p : will_kick){
                        p.kickPlayer("Az AFKolás nem megengedett!");
                        BattleCraft.logger.info(p.getName() + "afkert kickelve lett!");
                    }
                }
            }, 0L, 100L);
           
            TasksToCancel.add(TaskID);
        }
    Its a quite simple code, when players move, talk, shoot, etc.. AFKManager.Refresh is called.
    After about 15 minutes the server crashes with "memory limit exceeded".
    I guess my code causes the crash, but i don't know which part is wrong.
     
  2. Offline

    jayfella

    This isnt the solution to your problem, but static methods should not directly modify anything outside of its given variables. Don't use keywords if you have no idea what they do. It isnt there just so you can be lazy and access the methods from anywhere. A hashmap would server you better than a list in this situation, and would stop what I assume is a duplication bug in your code.
     
  3. Offline

    s0undx

    It can not duplicate because PlayerQuit and PlayerKick calls the Dispose function, which means that the AFK instance is removed from the list.
    Whats bad in using static keyword this way?
     
  4. Offline

    RealDope

    You're storing player instances in lists, thats a big no-no. Store their names instead. I'd imagine this is your problem. Player instances are constantly changing and tend to cause big memory leaks when stored.
     
  5. Offline

    s0undx

    Ok, i will rewrite my loop method, thanks.
     
  6. Offline

    s0undx

    Code:
        @SuppressWarnings("deprecation")
        public void TickAFKLoop(){
            int TaskID = Bukkit.getServer().getScheduler().scheduleAsyncRepeatingTask(this, new Runnable() {
                @Override
                public void run() {
                    List<String> will_kick = new ArrayList<String>();
                   
                    for(AFK a : AFKManager.afks){
                        a.AddSec();
                       
                        Player p = Bukkit.getPlayer(a.PlayerName);
                        if(p != null && !p.isOp()){
                            int LastAc = a.LastAction;
                            PVPMatch m = MapManager.GetMatchForPlayer(p);
                            int needed = 0;
                           
                            if(m != null){
                                needed = 18;
                            }else{
                                needed = 60;
                            }
                           
                            if(LastAc >= needed){
                                will_kick.add(p.getName());
                            }
                        }
                    }
                   
                    for(String p_s : will_kick){
                        if(Bukkit.getPlayer(p_s) != null){
                            Player p = Bukkit.getPlayer(p_s);
                            p.kickPlayer("Az AFKolás nem megengedett!");
                            BattleCraft.logger.info(Helper.ANSI_RED + p.getName() + " afkert kickelve lett!" + Helper.ANSI_RESET);       
                        }
                    }
                }
            }, 0L, 100L);
           
            TasksToCancel.add(TaskID);
        }
    It is still bugged, after the new loop method, if you have any idea please tell it.
     
Thread Status:
Not open for further replies.

Share This Page