JfrResultJsonSerializer.java
net.minecraft.util.profiling.jfr.serialize.JfrResultJsonSerializer
信息
- 全限定名:net.minecraft.util.profiling.jfr.serialize.JfrResultJsonSerializer
- 类型:public class
- 包:net.minecraft.util.profiling.jfr.serialize
- 源码路径:src/main/java/net/minecraft/util/profiling/jfr/serialize/JfrResultJsonSerializer.java
- 起始行号:L41
- 职责:
TODO
字段/常量
-
BYTES_PER_SECOND- 类型:
String - 修饰符:
private static final - 源码定位:
L42 - 说明:
TODO
- 类型:
-
COUNT- 类型:
String - 修饰符:
private static final - 源码定位:
L43 - 说明:
TODO
- 类型:
-
DURATION_NANOS_TOTAL- 类型:
String - 修饰符:
private static final - 源码定位:
L44 - 说明:
TODO
- 类型:
-
TOTAL_BYTES- 类型:
String - 修饰符:
private static final - 源码定位:
L45 - 说明:
TODO
- 类型:
-
COUNT_PER_SECOND- 类型:
String - 修饰符:
private static final - 源码定位:
L46 - 说明:
TODO
- 类型:
-
gson- 类型:
Gson - 修饰符:
final - 源码定位:
L47 - 说明:
TODO
- 类型:
内部类/嵌套类型
- 无
构造器
- 无
方法
下面的方法块按源码顺序生成。
private static void serializePacketId(PacketIdentification identifier, JsonObject output) @ L49
- 方法名:serializePacketId
- 源码定位:L49
- 返回类型:void
- 修饰符:private static
参数:
- identifier: PacketIdentification
- output: JsonObject
说明:
TODO
private static void serializeChunkId(ChunkIdentification identifier, JsonObject output) @ L54
- 方法名:serializeChunkId
- 源码定位:L54
- 返回类型:void
- 修饰符:private static
参数:
- identifier: ChunkIdentification
- output: JsonObject
说明:
TODO
public String format(JfrStatsResult jfrStats) @ L61
- 方法名:format
- 源码定位:L61
- 返回类型:String
- 修饰符:public
参数:
- jfrStats: JfrStatsResult
说明:
TODO
private JsonElement heap(GcHeapStat.Summary heapSummary) @ L83
- 方法名:heap
- 源码定位:L83
- 返回类型:JsonElement
- 修饰符:private
参数:
- heapSummary: GcHeapStat.Summary
说明:
TODO
private JsonElement structureGen(List<StructureGenStat> structureGenStats) @ L92
- 方法名:structureGen
- 源码定位:L92
- 返回类型:JsonElement
- 修饰符:private
参数:
- structureGenStats: List
说明:
TODO
private JsonElement chunkGen(List<Pair<ChunkStatus,TimedStatSummary<ChunkGenStat>>> chunkGenSummary) @ L141
- 方法名:chunkGen
- 源码定位:L141
- 返回类型:JsonElement
- 修饰符:private
参数:
- chunkGenSummary: List<Pair<ChunkStatus,TimedStatSummary
>>
说明:
TODO
private JsonElement threadAllocations(ThreadAllocationStat.Summary threadAllocationSummary) @ L180
- 方法名:threadAllocations
- 源码定位:L180
- 返回类型:JsonElement
- 修饰符:private
参数:
- threadAllocationSummary: ThreadAllocationStat.Summary
说明:
TODO
private JsonElement serverTicks(List<TickTimeStat> tickTimeStats) @ L189
- 方法名:serverTicks
- 源码定位:L189
- 返回类型:JsonElement
- 修饰符:private
参数:
- tickTimeStats: List
说明:
TODO
private JsonElement fps(List<FpsStat> fpsStats) @ L205
- 方法名:fps
- 源码定位:L205
- 返回类型:JsonElement
- 修饰符:private
参数:
- fpsStats: List
说明:
TODO
private JsonElement fileIO(JfrStatsResult jfrStats) @ L221
- 方法名:fileIO
- 源码定位:L221
- 返回类型:JsonElement
- 修饰符:private
参数:
- jfrStats: JfrStatsResult
说明:
TODO
private JsonElement fileIoSummary(FileIOStat.Summary io) @ L230
- 方法名:fileIoSummary
- 源码定位:L230
- 返回类型:JsonElement
- 修饰符:private
参数:
- io: FileIOStat.Summary
说明:
TODO
private JsonElement network(JfrStatsResult jfrStats) @ L247
- 方法名:network
- 源码定位:L247
- 返回类型:JsonElement
- 修饰符:private
参数:
- jfrStats: JfrStatsResult
说明:
TODO
private <T> JsonElement ioSummary(IoSummary<T> summary, BiConsumer<T,JsonObject> elementWriter) @ L254
- 方法名:ioSummary
- 源码定位:L254
- 返回类型:
JsonElement - 修饰符:private
参数:
- summary: IoSummary
- elementWriter: BiConsumer<T,JsonObject>
说明:
TODO
private JsonElement cpu(List<CpuLoadStat> cpuStats) @ L275
- 方法名:cpu
- 源码定位:L275
- 返回类型:JsonElement
- 修饰符:private
参数:
- cpuStats: List
说明:
TODO
代码
public class JfrResultJsonSerializer {
private static final String BYTES_PER_SECOND = "bytesPerSecond";
private static final String COUNT = "count";
private static final String DURATION_NANOS_TOTAL = "durationNanosTotal";
private static final String TOTAL_BYTES = "totalBytes";
private static final String COUNT_PER_SECOND = "countPerSecond";
final Gson gson = new GsonBuilder().setPrettyPrinting().setLongSerializationPolicy(LongSerializationPolicy.DEFAULT).create();
private static void serializePacketId(PacketIdentification identifier, JsonObject output) {
output.addProperty("protocolId", identifier.protocolId());
output.addProperty("packetId", identifier.packetId());
}
private static void serializeChunkId(ChunkIdentification identifier, JsonObject output) {
output.addProperty("level", identifier.level());
output.addProperty("dimension", identifier.dimension());
output.addProperty("x", identifier.x());
output.addProperty("z", identifier.z());
}
public String format(JfrStatsResult jfrStats) {
JsonObject root = new JsonObject();
root.addProperty("startedEpoch", jfrStats.recordingStarted().toEpochMilli());
root.addProperty("endedEpoch", jfrStats.recordingEnded().toEpochMilli());
root.addProperty("durationMs", jfrStats.recordingDuration().toMillis());
Duration worldCreationDuration = jfrStats.worldCreationDuration();
if (worldCreationDuration != null) {
root.addProperty("worldGenDurationMs", worldCreationDuration.toMillis());
}
root.add("heap", this.heap(jfrStats.heapSummary()));
root.add("cpuPercent", this.cpu(jfrStats.cpuLoadStats()));
root.add("network", this.network(jfrStats));
root.add("fileIO", this.fileIO(jfrStats));
root.add("fps", this.fps(jfrStats.fps()));
root.add("serverTick", this.serverTicks(jfrStats.serverTickTimes()));
root.add("threadAllocation", this.threadAllocations(jfrStats.threadAllocationSummary()));
root.add("chunkGen", this.chunkGen(jfrStats.chunkGenSummary()));
root.add("structureGen", this.structureGen(jfrStats.structureGenStats()));
return this.gson.toJson((JsonElement)root);
}
private JsonElement heap(GcHeapStat.Summary heapSummary) {
JsonObject json = new JsonObject();
json.addProperty("allocationRateBytesPerSecond", heapSummary.allocationRateBytesPerSecond());
json.addProperty("gcCount", heapSummary.totalGCs());
json.addProperty("gcOverHeadPercent", heapSummary.gcOverHead());
json.addProperty("gcTotalDurationMs", heapSummary.gcTotalDuration().toMillis());
return json;
}
private JsonElement structureGen(List<StructureGenStat> structureGenStats) {
JsonObject root = new JsonObject();
Optional<TimedStatSummary<StructureGenStat>> optionalSummary = TimedStatSummary.summary(structureGenStats);
if (optionalSummary.isEmpty()) {
return root;
} else {
TimedStatSummary<StructureGenStat> summary = optionalSummary.get();
JsonArray structureJsonArray = new JsonArray();
root.add("structure", structureJsonArray);
structureGenStats.stream()
.collect(Collectors.groupingBy(StructureGenStat::structureName))
.forEach(
(structureName, timedStat) -> {
Optional<TimedStatSummary<StructureGenStat>> optionalStatSummary = TimedStatSummary.summary((List<StructureGenStat>)timedStat);
if (!optionalStatSummary.isEmpty()) {
TimedStatSummary<StructureGenStat> statSummary = optionalStatSummary.get();
JsonObject structureJson = new JsonObject();
structureJsonArray.add(structureJson);
structureJson.addProperty("name", structureName);
structureJson.addProperty("count", statSummary.count());
structureJson.addProperty("durationNanosTotal", statSummary.totalDuration().toNanos());
structureJson.addProperty("durationNanosAvg", statSummary.totalDuration().toNanos() / statSummary.count());
JsonObject percentiles = Util.make(new JsonObject(), self -> structureJson.add("durationNanosPercentiles", self));
statSummary.percentilesNanos().forEach((percentile, v) -> percentiles.addProperty("p" + percentile, v));
Function<StructureGenStat, JsonElement> structureGenStatJsonGenerator = structureGen -> {
JsonObject result = new JsonObject();
result.addProperty("durationNanos", structureGen.duration().toNanos());
result.addProperty("chunkPosX", structureGen.chunkPos().x());
result.addProperty("chunkPosZ", structureGen.chunkPos().z());
result.addProperty("structureName", structureGen.structureName());
result.addProperty("level", structureGen.level());
result.addProperty("success", structureGen.success());
return result;
};
root.add("fastest", structureGenStatJsonGenerator.apply(summary.fastest()));
root.add("slowest", structureGenStatJsonGenerator.apply(summary.slowest()));
root.add(
"secondSlowest",
(JsonElement)(summary.secondSlowest() != null
? structureGenStatJsonGenerator.apply(summary.secondSlowest())
: JsonNull.INSTANCE)
);
}
}
);
return root;
}
}
private JsonElement chunkGen(List<Pair<ChunkStatus, TimedStatSummary<ChunkGenStat>>> chunkGenSummary) {
JsonObject json = new JsonObject();
if (chunkGenSummary.isEmpty()) {
return json;
} else {
json.addProperty("durationNanosTotal", chunkGenSummary.stream().mapToDouble(it -> it.getSecond().totalDuration().toNanos()).sum());
JsonArray chunkJsonArray = Util.make(new JsonArray(), self -> json.add("status", self));
for (Pair<ChunkStatus, TimedStatSummary<ChunkGenStat>> summaryByStatus : chunkGenSummary) {
TimedStatSummary<ChunkGenStat> chunkStat = summaryByStatus.getSecond();
JsonObject chunkStatusJson = Util.make(new JsonObject(), chunkJsonArray::add);
chunkStatusJson.addProperty("state", summaryByStatus.getFirst().toString());
chunkStatusJson.addProperty("count", chunkStat.count());
chunkStatusJson.addProperty("durationNanosTotal", chunkStat.totalDuration().toNanos());
chunkStatusJson.addProperty("durationNanosAvg", chunkStat.totalDuration().toNanos() / chunkStat.count());
JsonObject percentiles = Util.make(new JsonObject(), self -> chunkStatusJson.add("durationNanosPercentiles", self));
chunkStat.percentilesNanos().forEach((percentile, value) -> percentiles.addProperty("p" + percentile, value));
Function<ChunkGenStat, JsonElement> chunkGenStatJsonGenerator = chunk -> {
JsonObject chunkGenStatJson = new JsonObject();
chunkGenStatJson.addProperty("durationNanos", chunk.duration().toNanos());
chunkGenStatJson.addProperty("level", chunk.level());
chunkGenStatJson.addProperty("chunkPosX", chunk.chunkPos().x());
chunkGenStatJson.addProperty("chunkPosZ", chunk.chunkPos().z());
chunkGenStatJson.addProperty("worldPosX", chunk.worldPos().x());
chunkGenStatJson.addProperty("worldPosZ", chunk.worldPos().z());
return chunkGenStatJson;
};
chunkStatusJson.add("fastest", chunkGenStatJsonGenerator.apply(chunkStat.fastest()));
chunkStatusJson.add("slowest", chunkGenStatJsonGenerator.apply(chunkStat.slowest()));
chunkStatusJson.add(
"secondSlowest",
(JsonElement)(chunkStat.secondSlowest() != null ? chunkGenStatJsonGenerator.apply(chunkStat.secondSlowest()) : JsonNull.INSTANCE)
);
}
return json;
}
}
private JsonElement threadAllocations(ThreadAllocationStat.Summary threadAllocationSummary) {
JsonArray threads = new JsonArray();
threadAllocationSummary.allocationsPerSecondByThread().forEach((threadName, bytesPerSecond) -> threads.add(Util.make(new JsonObject(), json -> {
json.addProperty("thread", threadName);
json.addProperty("bytesPerSecond", bytesPerSecond);
})));
return threads;
}
private JsonElement serverTicks(List<TickTimeStat> tickTimeStats) {
if (tickTimeStats.isEmpty()) {
return JsonNull.INSTANCE;
} else {
JsonObject json = new JsonObject();
double[] tickTimesMs = tickTimeStats.stream().mapToDouble(tickTimeStat -> tickTimeStat.currentAverage().toNanos() / 1000000.0).toArray();
DoubleSummaryStatistics summary = DoubleStream.of(tickTimesMs).summaryStatistics();
json.addProperty("minMs", summary.getMin());
json.addProperty("averageMs", summary.getAverage());
json.addProperty("maxMs", summary.getMax());
Map<Integer, Double> percentiles = Percentiles.evaluate(tickTimesMs);
percentiles.forEach((percentile, value) -> json.addProperty("p" + percentile, value));
return json;
}
}
private JsonElement fps(List<FpsStat> fpsStats) {
if (fpsStats.isEmpty()) {
return JsonNull.INSTANCE;
} else {
JsonObject json = new JsonObject();
int[] fps = fpsStats.stream().mapToInt(FpsStat::fps).toArray();
IntSummaryStatistics summary = IntStream.of(fps).summaryStatistics();
json.addProperty("minFPS", summary.getMin());
json.addProperty("averageFPS", summary.getAverage());
json.addProperty("maxFPS", summary.getMax());
Map<Integer, Double> percentiles = Percentiles.evaluate(fps);
percentiles.forEach((percentile, value) -> json.addProperty("p" + percentile, value));
return json;
}
}
private JsonElement fileIO(JfrStatsResult jfrStats) {
JsonObject json = new JsonObject();
json.add("write", this.fileIoSummary(jfrStats.fileWrites()));
json.add("read", this.fileIoSummary(jfrStats.fileReads()));
json.add("chunksRead", this.ioSummary(jfrStats.readChunks(), JfrResultJsonSerializer::serializeChunkId));
json.add("chunksWritten", this.ioSummary(jfrStats.writtenChunks(), JfrResultJsonSerializer::serializeChunkId));
return json;
}
private JsonElement fileIoSummary(FileIOStat.Summary io) {
JsonObject json = new JsonObject();
json.addProperty("totalBytes", io.totalBytes());
json.addProperty("count", io.counts());
json.addProperty("bytesPerSecond", io.bytesPerSecond());
json.addProperty("countPerSecond", io.countsPerSecond());
JsonArray topContributors = new JsonArray();
json.add("topContributors", topContributors);
io.topTenContributorsByTotalBytes().forEach(contributor -> {
JsonObject contributorJson = new JsonObject();
topContributors.add(contributorJson);
contributorJson.addProperty("path", contributor.getFirst());
contributorJson.addProperty("totalBytes", contributor.getSecond());
});
return json;
}
private JsonElement network(JfrStatsResult jfrStats) {
JsonObject json = new JsonObject();
json.add("sent", this.ioSummary(jfrStats.sentPacketsSummary(), JfrResultJsonSerializer::serializePacketId));
json.add("received", this.ioSummary(jfrStats.receivedPacketsSummary(), JfrResultJsonSerializer::serializePacketId));
return json;
}
private <T> JsonElement ioSummary(IoSummary<T> summary, BiConsumer<T, JsonObject> elementWriter) {
JsonObject json = new JsonObject();
json.addProperty("totalBytes", summary.getTotalSize());
json.addProperty("count", summary.getTotalCount());
json.addProperty("bytesPerSecond", summary.getSizePerSecond());
json.addProperty("countPerSecond", summary.getCountsPerSecond());
JsonArray topContributors = new JsonArray();
json.add("topContributors", topContributors);
summary.largestSizeContributors().forEach(contributor -> {
JsonObject contributorJson = new JsonObject();
topContributors.add(contributorJson);
T identifier = contributor.getFirst();
IoSummary.CountAndSize countAndSize = contributor.getSecond();
elementWriter.accept(identifier, contributorJson);
contributorJson.addProperty("totalBytes", countAndSize.totalSize());
contributorJson.addProperty("count", countAndSize.totalCount());
contributorJson.addProperty("averageSize", countAndSize.averageSize());
});
return json;
}
private JsonElement cpu(List<CpuLoadStat> cpuStats) {
JsonObject json = new JsonObject();
BiFunction<List<CpuLoadStat>, ToDoubleFunction<CpuLoadStat>, JsonObject> transformer = (cpuLoadStats, extractor) -> {
JsonObject jsonGroup = new JsonObject();
DoubleSummaryStatistics stats = cpuLoadStats.stream().mapToDouble(extractor).summaryStatistics();
jsonGroup.addProperty("min", stats.getMin());
jsonGroup.addProperty("average", stats.getAverage());
jsonGroup.addProperty("max", stats.getMax());
return jsonGroup;
};
json.add("jvm", transformer.apply(cpuStats, CpuLoadStat::jvm));
json.add("userJvm", transformer.apply(cpuStats, CpuLoadStat::userJvm));
json.add("system", transformer.apply(cpuStats, CpuLoadStat::system));
return json;
}
}引用的其他类
-
- 引用位置:
方法调用 - 关联成员:
Util.make()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Percentiles.evaluate()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/方法调用 - 关联成员:
TimedStatSummary.summary()
- 引用位置:
-
- 引用位置:
参数
- 引用位置: