JDK-8235402 : Incorrect warning message in jcmd GC.class_histogram because of CDS
  • Type: Bug
  • Component: core-svc
  • Sub-Component: tools
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2019-12-05
  • Updated: 2024-09-12
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Duplicate :  
Relates :  
Description
$ jcmd 21844 GC.class_stats
21844:
WARNING: Ran out of C-heap; undercounted 368 total instances in data below
Index Super InstBytes KlassBytes annotations CpAll MethodCount Bytecodes MethodAll ROAll RWAll Total ClassName
    1 -1 3176392 512 0 0 0 0 0 24 624 648 [I
    2 -1 339752 512 0 0 0 0 0 24 624 648 [B
    3 35 169128 680 136 17024 123 5375 33856 23816 29856 53672 java.lang.String
    4 35 157488 784 0 23424 148 5833 38424 29096 36176 65272 java.lang.Class
[...]

but we didn't run out of C-heap.

The code path is:
    size_t missed_count = populate_table(&cit);
    if (missed_count != 0) {
      st->print_cr("WARNING: Ran out of C-heap; undercounted " SIZE_FORMAT
                   " total instances in data below",
                   missed_count);
    }
---
size_t HeapInspection::populate_table(KlassInfoTable* cit, BoolObjectClosure *filter) {
  ResourceMark rm;

  RecordInstanceClosure ric(cit, filter);
  Universe::heap()->object_iterate(&ric);
  return ric.missed_count();
}
---
  void do_object(oop obj) {
    if (should_visit(obj)) {
      if (!_cit->record_instance(obj)) {
        _missed_count++;
      }
    }
  }
---
bool KlassInfoTable::record_instance(const oop obj) {
  Klass*        k = obj->klass();
  KlassInfoEntry* elt = lookup(k);
  // elt may be NULL if it's a new klass for which we
  // could not allocate space for a new entry in the hashtable.
  if (elt != NULL) {
    elt->set_count(elt->count() + 1);
    elt->set_words(elt->words() + obj->size());
    _size_of_instances_in_words += obj->size();
    return true;
  } else {
    return false;
  }
}
---
KlassInfoEntry* KlassInfoTable::lookup(Klass* k) {
  uint         idx = hash(k) % _num_buckets;
  assert(_buckets != NULL, "Allocation failure should have been caught");
  KlassInfoEntry*  e   = _buckets[idx].lookup(k);
  // Lookup may fail if this is a new klass for which we
  // could not allocate space for an new entry, or if it's
  // an archived class that we haven't loaded yet.
  assert(e == NULL || k == e->klass(), "must be equal");
  return e;
}

See the last comment.

Comments
[~mwthomps] I don't remember in what context this was found. Maybe [~iklam] remembers given that he also reported the same bug a couple of months before my bug.
07-08-2024

S12Y triage team: [~stefank] We need information on how to reproduce. Does this happen every time you run GC.class_histogram with CDS enabled?
06-08-2024

Another ad-hoc hashtable.
06-12-2019