RFR: 7393: Add vanilla Java JSON serializer for IItemCollections

Alex Ciminian github.com+348973+cimi at openjdk.java.net
Tue Sep 7 12:57:50 UTC 2021


## What is this?

This PR adds a JSON serialiser for IItemCollections, with no other library dependencies. This implementation was originally done in #225 with the goal of providing JSON data directly to the browser over a WebSocket. 

We could use this as a generic representation of events to drive all visualisations we display in JMC since all structures (tree, graph etc) can be constructed from this base format. This would ensure a uniform interface for all visualisations (they could all expect event JSON data). 

## Serialized event structure

The serialized recording currently looks like this:


{
  "events": [{
    "eventType": "<type name>",
    "attributes": {
      "<attr1_name>": "<attr1_value>",
      "<attr2_name>": "<attr2_value>"
    }
  }]
} 


We've previously discussed having a `metadata` section in the JSON file in order to avoid repeating the attribute names - this is not implemented yet and I'd like to understand better how we want it to look like. It would be good to have a consistent representation of the event types and attributes across recordings so i.e. we don't encode them to different symbols and then have the same item represented in different ways. Since the encoding table will be shipped with the serialised items, in practice they can be decoded to the same thing but I'm not sure the benefit is worth the complexity. The only benefit I see for this is having a smaller document size, but we can probably get better compression if we just use zip.

## Testing and benchmarking

This PR currently has no tests because I wasn't sure how we want to run them here and what test data I can use. [This project, jmc-json-benchmarks](https://github.com/cimi/jmc-json-benchmarks), has the same code with tests and also has logic to benchmark different JSON serialisation implementations using JMH. While doing the JMH analysis, we found that FastJSON is significantly faster compared to this ad-hoc implementation, but for simplicity we can start with this implementation and replace later if performance becomes an issue.

You can see the benchmark results here: https://jmh.morethan.io/?source=https://raw.githubusercontent.com/cimi/jmc-json-benchmarks/master/all-results.json

## Examples of serialised events

These examples were taken from the test cases used to validate the implementation, you can see the full test output here:

* https://github.com/cimi/jmc-json-benchmarks/blob/master/src/test/resources/latency_before.json
* https://github.com/cimi/jmc-json-benchmarks/blob/master/src/test/resources/wldf.json

(The number of events serialised from the recording was truncated).

<details>
  <summary>EJB_Pool_Manager_Pre_Invoke</summary>
  

{
    "eventType": "http://www.oracle.com/wls/flightrecorder/medium/wls/EJB/EJB_Pool_Manager_Pre_Invoke",
    "attributes": {
      "(endTime)": 1384767793251009019,
      "eventThread": "[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'",
      "stackTrace": {
        "frames": [{
          "name": "weblogic.diagnostics.instrumentation.gathering.FlightRecorderEventHelper#recordStatelessEvent(Lweblogic/diagnostics/instrumentation/DiagnosticMonitor;Lweblogic/diagnostics/instrumentation/JoinPoint;)V",
          "line": 92,
          "type": "INTERPRETED"
        }, {
          "name": "weblogic.diagnostics.instrumentation.action.FlightRecorderStatelessAction#process(Lweblogic/diagnostics/instrumentation/JoinPoint;)V",
          "line": 51,
          "type": "INTERPRETED"
        }, [... many others ...], {
          "name": "weblogic.work.ExecuteThread#run()V",
          "line": 248,
          "type": "INTERPRETED"
        }]
      },
      "userID": "<anonymous>",
      "returnValue": "",
      "methodName": "preInvoke",
      "className": "weblogic.ejb.container.manager.StatelessManager",
      "transactionID": "BEA1-000217F1E993CDB6E1F6",
      "RCID": null,
      "RID": null,
      "ECID": "8ec006a7-30e9-4fac-be7f-716f42d3cbc8-0000001c",
      "ejbMethodName": null,
      "ejbName": null,
      "componentName": null,
      "applicationName": null,
      "subsystem": "EJB"
    }

</details>

<details>
  <summary>jdk.PSHeapSummary</summary>


{
    "eventType": "jdk.PSHeapSummary",
    "attributes": {
      "(endTime)": 1384767779307774408,
      "gcId": 4,
      "when": "After GC",
      "oldSpace:start": 3758096384,
      "oldSpace:committedEnd": 3937402880,
      "oldSpace:committedSize": 179306496,
      "oldSpace:reservedEnd": 4115660800,
      "oldSpace:reservedSize": 357564416,
      "oldObjectSpace:start": 3758096384,
      "oldObjectSpace:end": 3937402880,
      "oldObjectSpace:used": 50007536,
      "oldObjectSpace:size": 179306496,
      "youngSpace:start": 4115660800,
      "youngSpace:committedEnd": 4294967296,
      "youngSpace:committedSize": 179306496,
      "youngSpace:reservedEnd": 4294967296,
      "youngSpace:reservedSize": 179306496,
      "edenSpace:start": 4115660800,
      "edenSpace:end": 4272947200,
      "edenSpace:used": 0,
      "edenSpace:size": 157286400,
      "fromSpace:start": 4272947200,
      "fromSpace:end": 4283957248,
      "fromSpace:used": 10977416,
      "fromSpace:size": 11010048,
      "toSpace:start": 4283957248,
      "toSpace:end": 4294967296,
      "toSpace:used": 0,
      "toSpace:size": 11010048
    }

</details>

<details>
  <summary>jdk.NetworkUtilization</summary>


{
    "eventType": "jdk.NetworkUtilization",
    "attributes": {
      "startTime": 1541771978642206341,
      "networkInterface": "Hyper-V Virtual Ethernet Adapter #15",
      "readRate": 3349,
      "writeRate": 461
    }
}

-------------

Commit messages:
 - Add JSON serializer test using fixtures from StacktraceTestToolkit
 - Add vanilla Java JSON serializer for IItemCollections

Changes: https://git.openjdk.java.net/jmc/pull/279/files
 Webrev: https://webrevs.openjdk.java.net/?repo=jmc&pr=279&range=00
  Issue: https://bugs.openjdk.java.net/browse/JMC-7393
  Stats: 6572 lines in 5 files changed: 6572 ins; 0 del; 0 mod
  Patch: https://git.openjdk.java.net/jmc/pull/279.diff
  Fetch: git fetch https://git.openjdk.java.net/jmc pull/279/head:pull/279

PR: https://git.openjdk.java.net/jmc/pull/279


More information about the jmc-dev mailing list