Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8255884

Metaspace: chunk local commit counter may be stale

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Open
    • Priority: P4
    • Resolution: Unresolved
    • Affects Version/s: 16
    • Fix Version/s: tbd
    • Component/s: hotspot
    • Labels:
    • Subcomponent:
    • Understanding:
      Fix Understood
    • Introduced In Version:
      16

      Description

      The detailed metaspace report (`jcmd VM.metaspace`) shows the ChunkManager statistics. In these statistics, the commit counter for chunk levels < granule size may be wrong.

      Note that this does not affect the total commit counter, which is directly taken from the virtual memory layer, and which is always right.

      Background:

      The "truth" about the commit state of granules is kept inside VirtualSpaceNode in a bitmask ("commit mask"). Since this is a global resource and access to it is synchronized, each chunk keeps a commit watermark to know how the size of the range which is guaranteed to be committed and which can be used without asking. This counter is checked when allocating.

      This chunk-local commit boundary can get stale if the granule underneath the chunk gets committed and it did not notice. The only way this can happen is if the chunk is smaller than a granule and some in-granule neighbor was committed.

      That in itself works as designed and is totally benign. The chunk-local commit watermark will get silently corrected on the next allocation.

      But it messes up statistics a bit. Example:

      ```
      jcmd xxx VM.metaspace

      <snip>

      Chunk freelists:
      <snip>
              Both:

        4m: (none)
        2m: 2, capacity=4,00 MB, committed=0 bytes ( 0%)
        1m: 1, capacity=1,00 MB, committed=0 bytes ( 0%)
      512k: (none)
      256k: 2, capacity=512,00 KB, committed=0 bytes ( 0%)
      128k: 1, capacity=128,00 KB, committed=0 bytes ( 0%)
       64k: 2, capacity=128,00 KB, committed=0 bytes ( 0%)
       32k: 2, capacity=64,00 KB, committed=0 bytes ( 0%) <<<<< actually, these are committed
       16k: 1, capacity=16,00 KB, committed=0 bytes ( 0%) <<<<< these too
        8k: (none)
        4k: (none)
        2k: (none)
        1k: (none)
      Total word size: 5,83 MB, committed: 0 bytes ( 0%)

      ```

      In this example, the 32K and 16K chunks in the freelist had been committed as a side effect of comitting a neighboring chunk. Their watermarks are still at zero though and therefore they appear uncommitted here.

      The solution would be to - when a small chunk gets committed - adjust the watermarks of his in-granule neighbors. Then it looks like this:

      ```
              Both:

        4m: (none)
        2m: 3, capacity=6,00 MB, committed=0 bytes ( 0%)
        1m: 2, capacity=2,00 MB, committed=0 bytes ( 0%)
      512k: 1, capacity=512,00 KB, committed=0 bytes ( 0%)
      256k: (none)
      128k: 1, capacity=128,00 KB, committed=0 bytes ( 0%)
       64k: 1, capacity=64,00 KB, committed=0 bytes ( 0%)
       32k: 2, capacity=64,00 KB, committed=64,00 KB (100%) <<<<< good
       16k: 2, capacity=32,00 KB, committed=32,00 KB (100%) <<<<< good
        8k: (none)
        4k: (none)
        2k: (none)
        1k: (none)
      Total word size: 8,78 MB, committed: 96,00 KB ( 1%)
      ```


        Attachments

          Issue Links

            Activity

              People

              Assignee:
              stuefe Thomas Stuefe
              Reporter:
              stuefe Thomas Stuefe
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Dates

                Created:
                Updated: