Skip to content

Instantly share code, notes, and snippets.

View vladimirdolzhenko's full-sized avatar

Vladimir Dolzhenko vladimirdolzhenko

View GitHub Profile

Guava, Graal and Partial Escape Analysis

Recently java 10 release happened - in fact, Graal was available earlier, but now it is more easy to access and use it - Congratulations, you're running #Graal! - just add a couple options:

-XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler

What does it can provide for us and what kind of enhancements we can expect to get, and more over - what dirty-hacks could be dropped ?

Let's explore an example - looks a bit synthetic but based on a real production code.

ImmutableOopMap{rbx=Oop }pc offsets: 1684 1697 Compiled method (c2) 619 736 4 com.elastic.PartialEATest::allocate (55 bytes)
total in heap [0x00000001189a0c90,0x00000001189a1410] = 1920
relocation [0x00000001189a0e08,0x00000001189a0e38] = 48
main code [0x00000001189a0e40,0x00000001189a1060] = 544
stub code [0x00000001189a1060,0x00000001189a1078] = 24
oops [0x00000001189a1078,0x00000001189a10a0] = 40
metadata [0x00000001189a10a0,0x00000001189a10b0] = 16
scopes data [0x00000001189a10b0,0x00000001189a1210] = 352
scopes pcs [0x00000001189a1210,0x00000001189a13c0] = 432
dependencies [0x00000001189a13c0,0x00000001189a13c8] = 8
package com.elastic;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.profile.GCProfiler;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

Guava, Graal и Partial Escape Analysis

Недавно случился релиз десятки - и хотя Graal был доступен и раньше, теперь он стал ещё доступней - Congratulations, you're running #Graal! - просто добавьте

-XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler

Что конкретно это может нам дать и где можно ожидать улучшений, и какие велосипеды надо начинать выпиливать ?

Пример, который я буду рассматривать - частично надуманный, однако, основанный на реальных событиях.

jacoco issue #568

Steps to reproduce

  • JaCoCo version: 0.7.8, 0.7.9
  • Operating system: Windows, Linux
  • Tool integration: Gradle

let's say we have following class

9049090

There is an issue in SystemClock in java 9:

With JDK-8068730 SystemClock uses more precise timestamp provider, but it uses incorrect timeprovider for Windows - GetSystemTimeAsFileTime - see commit - that provides similar resolution as System.currentTimeMillis.

There is another timeprovider in WinAPI that gives wall-clock time with higher resolution - GetSystemTimePreciseAsFileTime

Simple show-case:

Precise timestamp

Пока идёт горячее обсуждение быть или нет быть jigsaw в java 9 и в каком виде ему быть - не стоит забывать про полезняшки, которые несёт с собой девятка - и одна из них - повышение точности Clock.systemUTC() - JDK-8068730 - начало обсуждения в core-libs-dev.

Что же было раньше ?

До java 8 был System.currentTimeMillis() и System.nanoTime(), и если первый давал wall clock время, но с миллисекундным разрешением, то второй даёт время с разрешением до наносекунд, но область применения ограничена измерением разности времён, причём в рамках одной jvm - и ни о каком использовании такой временной метки между разными машинами и быть не может.

Поэтому часто велосипедят свои precise timestamp дающие wall clock время с большим разрешением, чем у currentTimeMillis (используя jni со всеми вытекающими) - более подробно про ра

package com;
/*
MacOSX:
java 8
Benchmark Mode Cnt Score Error Units
ClockGranularity.granularityClockNanos avgt 2 999929.426 ns/op
ClockGranularity.granularityNanos avgt 2 41.420 ns/op
package com;
/**
$ uname -a
Darwin Vladimirs-MacBook-Pro.local 16.4.0 Darwin Kernel Version 16.4.0: Thu Dec 22 22:53:21 PST 2016; root:xnu-3789.41.3~3/RELEASE_X86_64 x86_64
$ java -version
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b16)
/*
$ export TZ=UTC
TZ = UTC
Benchmark Mode Cnt Score Error Units
TZTest.currentTimeMillis avgt 5 40.014 ± 1.383 ns/op
TZTest.instant avgt 5 47.798 ± 0.669 ns/op
TZTest.nano avgt 5 40.747 ± 1.040 ns/op
$ unset TZ