我在一个名为的文件中有以下程序Test.java
:
import sun.misc.Unsafe;
import java.lang.reflect.*;
public class Test {
public static void main(String[] args) throws Exception {
Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
Unsafe unsafe = (Unsafe) unsafeField.get(null);
long offset = unsafe.staticFieldOffset(unsafeField);
System.out.println(offset);
}
}
它只是获取一个Unsafe
实例,然后调用它的staticFieldOffset()
方法。
我用 编译它javac Test.java
,它输出一堆关于Unsafe
.
然后我运行生成的类文件java Test
并获得以下内容:
104
所以它有效。
现在,我用native-image --no-server --no-fallback Test app
.
[app:11806] classlist: 1,486.00 ms, 0.96 GB
[app:11806] (cap): 481.32 ms, 0.96 GB
[app:11806] setup: 1,628.06 ms, 0.96 GB
[app:11806] (clinit): 201.38 ms, 1.70 GB
[app:11806] (typeflow): 5,540.87 ms, 1.70 GB
[app:11806] (objects): 4,523.67 ms, 1.70 GB
[app:11806] (features): 251.65 ms, 1.70 GB
[app:11806] analysis: 10,741.48 ms, 1.70 GB
[app:11806] universe: 368.62 ms, 1.70 GB
[app:11806] (parse): 1,327.10 ms, 1.70 GB
[app:11806] (inline): 1,156.04 ms, 1.70 GB
[app:11806] (compile): 8,106.76 ms, 2.33 GB
[app:11806] compile: 10,998.36 ms, 2.33 GB
[app:11806] image: 765.81 ms, 2.33 GB
[app:11806] write: 137.50 ms, 2.33 GB
[app:11806] [total]: 26,315.42 ms, 2.33 GB
好的,最后,我用./app
. 结果如下:
Exception in thread "main" com.oracle.svm.core.jdk.UnsupportedFeatureError: Unsupported method of Unsafe
at com.oracle.svm.core.util.VMError.unsupportedFeature(VMError.java:86)
at jdk.internal.misc.Unsafe.staticFieldOffset(Unsafe.java:230)
at sun.misc.Unsafe.staticFieldOffset(Unsafe.java:662)
at Test.main(Test.java:9)
所以似乎在native模式下,它不支持Unsafe.staticFieldOffset()
方法。
有什么方法可以让它工作,还是应该在 GraalVM 代码中解决?这似乎阻碍了 Netty 在本机图像中的使用,请参阅https://github.com/netty/netty/issues/10051作为示例。
我正在使用 GraalVM 20.1:
openjdk version "11.0.7" 2020-04-14
OpenJDK Runtime Environment GraalVM CE 20.1.0 (build 11.0.7+10-jvmci-20.1-b02)
OpenJDK 64-Bit Server VM GraalVM CE 20.1.0 (build 11.0.7+10-jvmci-20.1-b02, mixed mode, sharing)
使用代理收集PS配置没有帮助。也就是说,当我添加-agentlib:native-image-agent=config-output-dir=target/config
到java
命令以收集有关反射的运行时数据和添加内容然后添加-H:ConfigurationFileDirectories=target/config
到native-image
命令时,生成的本机程序的行为相同。