简体   繁体   English

为什么GC日志中的某些行只显示堆大小的一个值?

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

Most lines in my GC log look like this: 我的GC日志中的大多数行看起来像这样:

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

The size in parentheses is the "commited heap", or (approximately) the size of the process as seen by the OS. 括号中的大小是“提交堆”,或(大约)操作系统看到的进程大小。 The two numbers before that ("a->b") show heap usage before and after GC. 之前的两个数字(“a-> b”)显示GC之前和之后的堆使用情况。

Now, regularly, I get lines like this: 现在,经常,我得到这样的行:

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

Do those mean that the heap usage was not changed by GC, or is this a different message? 那些意味着GC没有改变堆使用情况,还是这是一个不同的消息? I looked at Oracle's GC tuning tutorial and another page specifically about GC output , but couldn't find this type of message explained. 我查看了Oracle的GC调优教程另一个专门关于GC输出的页面 ,但是找不到这种类型的消息。

I'm using the Sun JVM (1.6.0.25), the Concurrent Collector ( -XX:+UseConcMarkSweepGC ) and the only output related startup option is -Xloggc:gc.log . 我正在使用Sun JVM(1.6.0.25),Concurrent Collector( -XX:+UseConcMarkSweepGC ),唯一与输出相关的启动选项是-Xloggc:gc.log

I've searched for "secs" in the source code of JDK 1.6 update 23 (most recent 1.6 version I could find it for) and for regex "[^"]*->[^"]*" through the GC code folders in hope of finding a lead. 我在JDK 1.6更新23的源代码中搜索了“secs”(我可以找到它的最新1.6版本),并通过GC代码文件夹搜索正则表达式“[^”] * - > [^“] *”希望找到一个领先者。 I've also searched through the OpenJDK 1.7 code. 我还搜索了OpenJDK 1.7代码。 Then I tried searching the entire HotSpot folder for "[^"]*->[^"]*"?.*secs. 然后我尝试在整个HotSpot文件夹中搜索“[^”] * - > [^“] *”?。* secs。 Yet, the only line of GC logging I've found that seems remotely related to what you're seeing is 然而,我发现的唯一GC记录线似乎与你所看到的有很大关系

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

That's in concurrentMarkSweepGeneration.cpp. 这是在concurrentMarkSweepGeneration.cpp中。 It doesn't look even close to the format you've seen. 它看起来与您看到的格式不太接近。 Either I'm not searching very well, or something changed in between update 23 and update 25 regarding GC logging. 要么我没有很好地搜索,要么在更新23和更新25之间有关GC记录的更改。

If anyone has a clearer idea of where to look or what to search on, I'll be glad to oblige. 如果有人更清楚地知道在哪里寻找或搜索什么,我将很乐意接受。

EDIT: wait, found something starting at line 827 of concurrentMarkSweepGeneration.cpp: 编辑:等待,发现从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);
  }
}

And that function's being called only here: 而这个函数只在这里调用:

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");
  }
}

It sure looks like what you're getting. 它确实看起来像你得到的。 I'm not so good at interpreting this code, but I'd say what you're seeing is simply a log line showing the current heap use followed by the committed heap size in parentheses, nothing more. 我不太擅长解释这段代码,但我会说你所看到的只是一条日志行,显示当前堆使用后跟括号中的已提交堆大小,仅此而已。 Basically the same info but without the use before garbage collection. 基本相同的信息,但垃圾收集前没有使用。

Can you list all gc-looging relevant jvm parameters? 你能列出所有gc-looging相关的jvm参数吗?

Looking at your output I don't think you are using 看看你的输出我觉得你没用

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

Also please check 还请检查

Explanation of Tomcat GC log statements Tomcat GC日志语句的说明

Java Garbage Collection Log messages Java垃圾收集日志消息

I think this line is initiated by TraceTime in timer.cpp which is called from CMS ( concurrentMarkSweepGeneration.cpp do_CMS_operation ) and ParNew ( parNewGeneration.cpp collect ). 我认为这一行是由TraceTime中的TraceTime启动的,它是从CMS( concurrentMarkSweepGeneration.cpp do_CMS_operation )和ParNew( parNewGeneration.cpp collectparNewGeneration.cpp collect This code seems the source 这段代码似乎是源代码

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);
    }
}

Therefore this is a statement of the total occupancy of the heap (sum of all generations) along with the time elapsed during the current GC operation. 因此,这是堆的总占用率(所有代的总和)以及当前GC操作期间经过的时间的陈述。 The time printed appears to be wall time as the timer ( os::elapsed_counter so this is gettimeofday on linux for example) is started when the TraceTime is instantiated and stopped/printed when it is destroyed. 打印时间似乎是作为计时器( os::elapsed_counter因此这是linux上的gettimeofday )的TraceTimeTraceTime被实例化并在销毁时停止/打印时启动。

I recommend you add verbose:gc to get more information if you want it. 我建议您添加verbose:gc以获取更多信息(如果需要)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM