Beispiel #1
0
 /**
  * Callback routine called by JVM after full gc run. Has two functions: 1) sets the amount of
  * memory to be cleaned from the cache by the Cleaner 2) sets the CAN_ALLOC flag to false if
  * memory level is critical
  *
  * <p>The callback happens in a system thread, and hence not through the usual water.Boot loader
  * - and so any touched classes are in the wrong class loader and you end up with new classes
  * with uninitialized global vars. Limit to touching global vars in the Boot class.
  */
 public void handleNotification(Notification notification, Object handback) {
   String notifType = notification.getType();
   if (notifType.equals(MemoryNotificationInfo.MEMORY_COLLECTION_THRESHOLD_EXCEEDED)) {
     // Memory used after this FullGC
     Boot.TIME_AT_LAST_GC = System.currentTimeMillis();
     Boot.HEAP_USED_AT_LAST_GC = _allMemBean.getHeapMemoryUsage().getUsed();
     Boot.kick_store_cleaner();
   }
 }
Beispiel #2
0
  // Set K/V cache goals.
  // Allow (or disallow) allocations.
  // Called from the Cleaner, when "cacheUsed" has changed significantly.
  // Called from any FullGC notification, and HEAP/POJO_USED changed.
  // Called on any OOM allocation
  public static void set_goals(String msg, boolean oom, long bytes) {
    // Our best guess of free memory, as of the last GC cycle
    final long heapUsed = Boot.HEAP_USED_AT_LAST_GC;
    final long timeGC = Boot.TIME_AT_LAST_GC;
    final long freeHeap = MEM_MAX - heapUsed;
    assert freeHeap >= 0
        : "I am really confused about the heap usage; MEM_MAX=" + MEM_MAX + " heapUsed=" + heapUsed;
    // Current memory held in the K/V store.
    final long cacheUsage = myHisto.histo(false)._cached;
    // Our best guess of POJO object usage: Heap_used minus cache used
    final long pojoUsedGC = Math.max(heapUsed - cacheUsage, 0);

    // Block allocations if:
    // the cache is > 7/8 MEM_MAX, OR
    // we cannot allocate an equal amount of POJOs, pojoUsedGC > freeHeap.
    // Decay POJOS_USED by 1/8th every 5 sec: assume we got hit with a single
    // large allocation which is not repeating - so we do not need to have
    // double the POJO amount.
    // Keep at least 1/8th heap for caching.
    // Emergency-clean the cache down to the blocking level.
    long d = MEM_CRITICAL;
    // Decay POJO amount
    long p = pojoUsedGC;
    long age = (System.currentTimeMillis() - timeGC); // Age since last FullGC
    age = Math.min(age, 10 * 60 * 1000); // Clip at 10mins
    while ((age -= 5000) > 0) p = p - (p >> 3); // Decay effective POJO by 1/8th every 5sec
    d -= 2 * p - bytes; // Allow for the effective POJO, and again to throttle GC rate
    d = Math.max(d, MEM_MAX >> 3); // Keep at least 1/8th heap
    H2O.Cleaner.DESIRED = d;

    String m = "";
    if (cacheUsage > H2O.Cleaner.DESIRED) {
      m = (CAN_ALLOC ? "Blocking!  " : "blocked:   ");
      if (oom) setMemLow(); // Stop allocations; trigger emergency clean
      Boot.kick_store_cleaner();
    } else { // Else we are not *emergency* cleaning, but may be lazily cleaning.
      if (!CAN_ALLOC) m = "Unblocking:";
      else m = "MemGood:   ";
      setMemGood();
      if (oom) // Confused? OOM should have FullGCd should have set low-mem goals
      Log.warn(
            Sys.CLEAN,
            "OOM but no FullGC callback?  MEM_MAX = "
                + MEM_MAX
                + ", DESIRED = "
                + d
                + ", CACHE = "
                + cacheUsage
                + ", p = "
                + p
                + ", bytes = "
                + bytes);
    }

    // No logging if under memory pressure: can deadlock the cleaner thread
    if (Log.flag(Sys.CLEAN)) {
      String s =
          m
              + msg
              + ", HEAP_LAST_GC="
              + (heapUsed >> 20)
              + "M, KV="
              + (cacheUsage >> 20)
              + "M, POJO="
              + (pojoUsedGC >> 20)
              + "M, free="
              + (freeHeap >> 20)
              + "M, MAX="
              + (MEM_MAX >> 20)
              + "M, DESIRED="
              + (H2O.Cleaner.DESIRED >> 20)
              + "M"
              + (oom ? " OOM!" : " NO-OOM");
      if (CAN_ALLOC) Log.debug(Sys.CLEAN, s);
      else Log.unwrap(System.err, s);
    }
  }