簡體   English   中英

為什么GC日志中的某些行只顯示堆大小的一個值?

[英]Why do some lines in my GC log show only one value for the heap size?

我的GC日志中的大多數行看起來像這樣:

203.558:[GC 326391K-> 324672K(4192192K),0.0452610秒]

括號中的大小是“提交堆”,或(大約)操作系統看到的進程大小。 之前的兩個數字(“a-> b”)顯示GC之前和之后的堆使用情況。

現在,經常,我得到這樣的行:

42381.926:[GC 10996274K(12565888K),0.0651560秒]

那些意味着GC沒有改變堆使用情況,還是這是一個不同的消息? 我查看了Oracle的GC調優教程另一個專門關於GC輸出的頁面 ,但是找不到這種類型的消息。

我正在使用Sun JVM(1.6.0.25),Concurrent Collector( -XX:+UseConcMarkSweepGC ),唯一與輸出相關的啟動選項是-Xloggc:gc.log

我在JDK 1.6更新23的源代碼中搜索了“secs”(我可以找到它的最新1.6版本),並通過GC代碼文件夾搜索正則表達式“[^”] * - > [^“] *”希望找到一個領先者。 我還搜索了OpenJDK 1.7代碼。 然后我嘗試在整個HotSpot文件夾中搜索“[^”] * - > [^“] *”?。* secs。 然而,我發現的唯一GC記錄線似乎與你所看到的有很大關系

gclog_or_tty->print("[%s-concurrent-%s: %3.3f/%3.3f secs]",
             _collector->cmsGen()->short_name(),
             _phase, _collector->timerValue(), _wallclock.seconds());

這是在concurrentMarkSweepGeneration.cpp中。 它看起來與您看到的格式不太接近。 要么我沒有很好地搜索,要么在更新23和更新25之間有關GC記錄的更改。

如果有人更清楚地知道在哪里尋找或搜索什么,我將很樂意接受。

編輯:等待,發現從concurrentMarkSweepGeneration.cpp的第827行開始:

void ConcurrentMarkSweepGeneration::printOccupancy(const char *s) {
  GenCollectedHeap* gch = GenCollectedHeap::heap();
  if (PrintGCDetails) {
    if (Verbose) {
      gclog_or_tty->print(" [%d %s-%s: "SIZE_FORMAT"("SIZE_FORMAT")]",
        level(), short_name(), s, used(), capacity());
    } else {
      gclog_or_tty->print(" [%d %s-%s: "SIZE_FORMAT"K("SIZE_FORMAT"K)]",
        level(), short_name(), s, used() / K, capacity() / K);
    }
  }
  if (Verbose) {
    gclog_or_tty->print(" "SIZE_FORMAT"("SIZE_FORMAT")",
              gch->used(), gch->capacity());
  } else {
    gclog_or_tty->print(" "SIZE_FORMAT"K("SIZE_FORMAT"K)",
              gch->used() / K, gch->capacity() / K);
  }
}

而這個函數只在這里調用:

void CMSCollector::do_CMS_operation(CMS_op_type op) {
  gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
  TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
  TraceTime t("GC", PrintGC, !PrintGCDetails, gclog_or_tty);
  TraceCollectorStats tcs(counters());

  switch (op) {
    case CMS_op_checkpointRootsInitial: {
      checkpointRootsInitial(true);       // asynch
      if (PrintGC) {
        _cmsGen->printOccupancy("initial-mark");
      }
      break;
    }
    case CMS_op_checkpointRootsFinal: {
      checkpointRootsFinal(true,    // asynch
                           false,   // !clear_all_soft_refs
                           false);  // !init_mark_was_synchronous
      if (PrintGC) {
        _cmsGen->printOccupancy("remark");
      }
      break;
    }
    default:
      fatal("No such CMS_op");
  }
}

它確實看起來像你得到的。 我不太擅長解釋這段代碼,但我會說你所看到的只是一條日志行,顯示當前堆使用后跟括號中的已提交堆大小,僅此而已。 基本相同的信息,但垃圾收集前沒有使用。

你能列出所有gc-looging相關的jvm參數嗎?

看看你的輸出我覺得你沒用

-verbose:gc -XX:+ PrintGCTimeStamps -XX:+ PrintGCDetails

還請檢查

Tomcat GC日志語句的說明

Java垃圾收集日志消息

我認為這一行是由TraceTime中的TraceTime啟動的,它是從CMS( concurrentMarkSweepGeneration.cpp do_CMS_operation )和ParNew( parNewGeneration.cpp collectparNewGeneration.cpp collect 這段代碼似乎是源代碼

void ConcurrentMarkSweepGeneration::printOccupancy(const char *s) {
    GenCollectedHeap* gch = GenCollectedHeap::heap();
    if (PrintGCDetails) {
      if (Verbose) {
        gclog_or_tty->print(" [%d %s-%s: "SIZE_FORMAT"("SIZE_FORMAT")]",
          level(), short_name(), s, used(), capacity());
    } else {
        gclog_or_tty->print(" [%d %s-%s: "SIZE_FORMAT"K("SIZE_FORMAT"K)]",
          level(), short_name(), s, used() / K, capacity() / K);
      }
    }
    if (Verbose) {
      gclog_or_tty->print(" "SIZE_FORMAT"("SIZE_FORMAT")",
                gch->used(), gch->capacity());
    } else {
      gclog_or_tty->print(" "SIZE_FORMAT"K("SIZE_FORMAT"K)",
              gch->used() / K, gch->capacity() / K);
    }
}

因此,這是堆的總占用率(所有代的總和)以及當前GC操作期間經過的時間的陳述。 打印時間似乎是作為計時器( os::elapsed_counter因此這是linux上的gettimeofday )的TraceTimeTraceTime被實例化並在銷毀時停止/打印時啟動。

我建議您添加verbose:gc以獲取更多信息(如果需要)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM