JDK-8221994 : Improve consistency between actual values and MemoryUsage.used() in MBeans
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: gc
  • Affected Version: 13
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2019-04-04
  • Updated: 2020-06-03
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
Relates :  
Relates :  
Description
There is inconsistent pair of values between actual values(seen from gc) and MemoryMXBeans(MemoryUsage.used()).

The related code is:
G1MonitoringSupport::recalculate_sizes() {
...
  _overall_used = _g1h->used_unlocked();
  _eden_space_used = _g1h->eden_regions_used_bytes();
...
  _old_gen_used = subtract_up_to_zero(_overall_used, _eden_space_used + _survivor_space_used);
...
}
and
G1CollectedHeap::retire_mutator_alloc_region() {
...
  increase_used(allocated_bytes);
  _eden.add_used_bytes(allocated_bytes);
...
}

subtract_up_to_zero(size_t x, size_t y) {
    if (x > y) {
      return x - y;
    } else {
      return 0;
    }

subtract_up_to_zero() is used prevent followed assert failure because of inconsistent values.

Popped up during the review of JDK-8218049.

Kim Barrett suggested using Double buffering or GlobalCounter.
Comments
Here's my idea for using GlobalCounter for the synchronization. retire: begin_critical_section() update_heap_used(amount) update_eden_used(amount) end_critical_section() monitor: do heap_used = get_heap_used() eden_used = get_eden_used() synchronize while (heap_used != get_heap_used() || eden_used != get_eden_used()) // heap_used and eden_used are consistent inconsistent interleaving 1: T2-a, T1-a, T1-b, T2-b T2 will see that heap_used has changed, and retry. inconsistent interleaving 2: T1-a, T2-a, T2-b, T1-b T2 synchronize will wait until after T1-b, then T2 will see that eden_used has changed, and retry. A sufficiently high rate of retirements could keep the monitor spinning, but I doubt (hope?) that won't be a problem in practice. And yes, this flips the usual reader in critical section, writer synchronizes RCU usage model.
05-04-2019