1. Этот сайт использует файлы cookie. Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie. Узнать больше.
  2. Здравствуй путник Гость ознакомься с Правилами форума

  3. Не знаешь как разобраться с группами на форуме? Тогда тебе сюда Группы на форуме
  4. На форуме работает хайд, где вы можете скрыть информацию от пользователей по определенным критериям Хайд
  5. На форуме работает репутация, где вы можете поблагодарить пользователей. Рассчитывается репутация по индивидуальным критериям Репутация
  6. С списком обновлений можно знакомиться в этой теме Обновления форума

Скрыть объявление

Привет посетитель! У нас на форуме тебе откроются дополнительные разделы, которые скрыты от гостей! А так же ты найдёшь много полезной информации.

Memory Watching

Уведомлялка о расходе памяти сервера

  1. n3k0Nation
    Простая уведомлялка о критическом состоянии памяти на сервере. Поддерживает дамп памяти (который выпилят в Java 9), если Full GC не произошло (т.к. получается, то все объекты живы и у нас утечка памяти).
    Поддерживает: G1, Marksweep, Scavenge.

    Код:
    package fork2.gs.ext.sys;
    
    import java.lang.management.MemoryPoolMXBean;
    
    /**
     * @author PointerRage
     *
     */
    public interface IMemoryWatcher {
       void register(MemoryPoolMXBean pool);
       boolean isValid(MemoryPoolMXBean pool);
    }
    
    Код:
    package fork2.gs.ext.sys;
    
    import java.lang.management.ManagementFactory;
    import java.lang.management.MemoryPoolMXBean;
    import java.lang.management.MemoryType;
    
    import javax.management.NotificationEmitter;
    
    import lombok.extern.slf4j.Slf4j;
    
    /**
     * @author PointerRage
     *
     */
    @Slf4j
    public class DefaultWatcher implements IMemoryWatcher {
       protected DefaultWatcher() {
       }
       
       @Override
       public void register(MemoryPoolMXBean pool) {
         long max = pool.getUsage().getMax();
         pool.setUsageThreshold(Math.round(max * 0.85));
         
         NotificationEmitter emitter = (NotificationEmitter) ManagementFactory.getMemoryMXBean();
         emitter.addNotificationListener(new PoolListener(pool), null, null);
         log.info("Listened {}", pool.getName());
       }
    
       @Override
       public boolean isValid(MemoryPoolMXBean pool) { //for marksweep & scavenge
         return pool.getType() == MemoryType.HEAP && pool.isCollectionUsageThresholdSupported() && pool.getName().startsWith("PS Survivor");
       }
    }
    
    Код:
    package fork2.gs.ext.sys;
    
    import java.lang.management.ManagementFactory;
    import java.lang.management.MemoryPoolMXBean;
    import java.lang.management.MemoryType;
    
    import javax.management.NotificationEmitter;
    
    import lombok.extern.slf4j.Slf4j;
    
    /**
     * @author PointerRage
     *
     */
    @Slf4j
    public class G1Watcher implements IMemoryWatcher {
       protected G1Watcher() {
         
       }
       
       @Override
       public void register(MemoryPoolMXBean pool) {
         long max = pool.getUsage().getMax();
         pool.setUsageThreshold(Math.round(max * 0.85));
         
         NotificationEmitter emitter = (NotificationEmitter) ManagementFactory.getMemoryMXBean();
         emitter.addNotificationListener(new PoolListener(pool), null, null);
         log.info("Listened {}", pool.getName());
       }
       
       @Override
       public boolean isValid(MemoryPoolMXBean pool) { //for G1 GC its old gen
         return pool.getType() == MemoryType.HEAP && pool.isUsageThresholdSupported() && pool.isCollectionUsageThresholdSupported()
             && pool.getName().startsWith("G1");
       }
    }
    
    Код:
    package fork2.gs.ext.sys;
    
    import java.lang.management.ManagementFactory;
    import java.lang.management.MemoryNotificationInfo;
    import java.lang.management.MemoryPoolMXBean;
    import java.lang.management.MemoryUsage;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.concurrent.Future;
    import java.util.concurrent.TimeUnit;
    
    import javax.management.MBeanServer;
    import javax.management.Notification;
    import javax.management.NotificationListener;
    
    import net.sf.ehcache.config.MemoryUnit;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import ru.catssoftware.gameserver.ThreadPoolManager;
    import ru.catssoftware.gameserver.gmaccess.GmInteract;
    
    import com.sun.management.HotSpotDiagnosticMXBean;
    
    /**
     * @author PointerRage
     *
     */
    public class PoolListener implements NotificationListener {
       private final static Logger memLog = LoggerFactory.getLogger("MemLog");
       private final static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd_HH.mm");
       private final MemoryPoolMXBean pool;
       private Future<?> watch;
       
       protected PoolListener(MemoryPoolMXBean pool) {
         this.pool = pool;
       }
       
       @Override
       public void handleNotification(Notification notification, Object handback) {
         if(!notification.getType().equals(MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED)
             && !notification.getType().equals(MemoryNotificationInfo.MEMORY_COLLECTION_THRESHOLD_EXCEEDED))
           return;
         
         MemoryUsage usage = pool.getUsage();
         long used = usage.getUsed();
         long max = usage.getMax();
         long percent = Math.round((used / (double)max) * 100);
         
         memLog.warn("Critical memory usage {}% for {} pool. Usage: {}/{} mb.",
             percent, pool.getName(), MemoryUnit.BYTES.toMegaBytes(used), MemoryUnit.BYTES.toMegaBytes(max));
         
         GmInteract.getInstance().normalMsg("Critical memory usage {}% for {} pool. Usage: {}/{} mb.",
             percent, pool.getName(), MemoryUnit.BYTES.toMegaBytes(used), MemoryUnit.BYTES.toMegaBytes(max));
         
         if(watch != null && !watch.isDone()) {
           watch.cancel(false);
         }
         watch = ThreadPoolManager.getInstance().scheduleGeneral(() -> watchHeap(percent), 2, TimeUnit.MINUTES);
       }
       
       private void watchHeap(long percent) {
         MemoryUsage usage = pool.getUsage();
         long used = usage.getUsed();
         long max = usage.getMax();
         long actualPercent = Math.round((used / (double)max) * 100);
         
         if(actualPercent > percent) { //is memory leak or full gc?
           dump();
         }
         
         GmInteract.getInstance().normalMsg("Critical memory usage {}% for {} pool. Usage: {}/{} mb.",
             actualPercent, pool.getName(), MemoryUnit.BYTES.toMegaBytes(used), MemoryUnit.BYTES.toMegaBytes(max));
         GmInteract.getInstance().normalMsg("Please reboot server!");
       }
       
       private void dump() {
         MBeanServer server = ManagementFactory.getPlatformMBeanServer();
         HotSpotDiagnosticMXBean diagnosticBean;
         try {
           diagnosticBean = ManagementFactory.newPlatformMXBeanProxy(server, "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class);
         } catch(Throwable e) {
           memLog.warn("Failed to dump memory.");
           return;
         }
         
         String format = dateFormat.format(new Date());
         try {
           diagnosticBean.dumpHeap("./" + format + ".bin", true);
         } catch (Throwable e) {
           memLog.warn("Failed to dump memory.");
           return;
         }
         
         GmInteract.getInstance().normalMsg("Memory succefull dumped: {}.bin", format);
         memLog.warn("Memory succefull dumped: {}.bin", format);
       }
    
    }
    
    Код:
    package fork2.gs.ext.sys;
    
    import java.lang.management.ManagementFactory;
    import java.lang.management.MemoryPoolMXBean;
    import java.util.Arrays;
    import java.util.List;
    
    import lombok.Getter;
    import lombok.extern.slf4j.Slf4j;
    import fork2.startup.Singleton;
    import fork2.startup.Startup;
    
    /**
     * @author PointerRage
     *
     */
    @Startup("SystemInfo")
    @Singleton
    @Slf4j
    public class MemoryWatchManager {
       @Getter(lazy=true) private final static MemoryWatchManager instance = new MemoryWatchManager();
       private final List<IMemoryWatcher> watchers = Arrays.asList(new G1Watcher(), new DefaultWatcher());
       private MemoryWatchManager() {
         registerWatchers();
       }
       
       private void registerWatchers() {
         for(MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans()) {
           log.info("{}: {}", pool.getName(), pool.getUsage().toString());
           watchers.stream()
             .filter(watcher -> watcher.isValid(pool))
             .forEach(watcher -> watcher.register(pool));
         }
       }
    }
    
    Ethernal и kick нравится это.