栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

jmx的gc指标数据是如何获取的

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

jmx的gc指标数据是如何获取的

jmx会暴露进程开始运行后的gc总次数和gc总时间。这个数据究竟是怎么获取的。下面以ps为例。我们来查看一下流程。

for (GarbageCollectorMXBean garbageCollectorMBean : garbageCollectors) {
      String gcName = garbageCollectorMBean.getName();
      long gcCount = garbageCollectorMBean.getCollectionCount();
   
  }

java层面的api就是这一个样子,可以从mbean众读取gc的次数。
我们从接口找到实现类。发现这是一个native的方法。

public class GarbageCollectorImpl extends MemoryManagerImpl
    implements GarbageCollectorMXBean {

    protected GarbageCollectorImpl(String name) {
 super(name);
    }

    @Override
    public native long getCollectionCount();

根据jni的规则。我们找到具体的c实现。

JNIEXPORT jlong JNICALL Java_sun_management_GarbageCollectorImpl_getCollectionCount
  (JNIEnv *env, jobject mgr) {
    return jmm_interface->GetLongAttribute(env, mgr, JMM_GC_COUNT);
}

这里的JMM_GC_COUNT是个枚举。

static jlong get_gc_attribute(GCMemoryManager* mgr, jmmLongAttribute att) {
  switch (att) {
  case JMM_GC_TIME_MS:
    return mgr->gc_time_ms();

  case JMM_GC_COUNT:
    return mgr->gc_count();

  case JMM_GC_EXT_ATTRIBUTE_INFO_SIZE:
    // current implementation only has 1 ext attribute
    return 1;

  default:
    assert(0, "Unrecognized GC attribute");
    return -1;
  }
}

  size_t gc_count(){ return _num_collections; }

在实现的代码里,我们可以看到数据是直接从mgr的gc_count中获取的。gc_count是直接获取的一个成员变量_num_collections。

void GCMemoryManager::gc_end(bool recordPostGCUsage,
 bool recordAccumulatedGCTime,
 bool recordGCEndTime, bool countCollection,
 GCCause::Cause cause,
 bool allMemoryPoolsAffected) {
 …………
   _num_collections++;

GCMemoryManager的gc_end。在MemoryService中被调用到。

void MemoryService::gc_end(GCMemoryManager* manager, bool recordPostGCUsage,
      bool recordAccumulatedGCTime,
      bool recordGCEndTime, bool countCollection,
      GCCause::Cause cause,
      bool allMemoryPoolsAffected) {
  manager->gc_end(recordPostGCUsage, recordAccumulatedGCTime, recordGCEndTime,
    countCollection, cause, allMemoryPoolsAffected);
}

MemoryService在TraceMemoryManagerStats的析构函数里被调用。

TraceMemoryManagerStats::~TraceMemoryManagerStats() {
  MemoryService::gc_end(_gc_memory_manager, _recordPostGCUsage, _recordAccumulatedGCTime,
   _recordGCEndTime, _countCollection, _cause, _allMemoryPoolsAffected);
}

jvm很多的计数方式都是通过析构函数做的。TraceMemoryManagerStats就是我们需要找的对象。
TraceMemoryManagerStats分散在每个gc的实现里。下面是PSParallelCompact的部分

    TraceMemoryManagerStats tms(heap->old_gc_manager(), gc_cause);

这里的调用为了能准确的析构,专门把gc的代码放在了一个代码块里。通过声明周期的控制,达到跟踪数据的目的。

后面还有很多计数也在这里的code里。例如gclog

void PSOldGen::print_used_change(size_t prev_used) const {
  log_info(gc, heap)("%s: "  SIZE_FORMAT "K->" SIZE_FORMAT "K("  SIZE_FORMAT "K)",
      name(), prev_used / K, used_in_bytes() / K, capacity_in_bytes() / K);
}

还有jstat的值的变化

void ParallelScavengeHeap::update_counters() {
  young_gen()->update_counters();
  old_gen()->update_counters();
  metaspaceCounters::update_performance_counters();
  CompressedClassSpaceCounters::update_performance_counters();
}

nmt的变化

    // Track memory usage and detect low memory
    MemoryService::track_memory_usage();
转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号