-
Notifications
You must be signed in to change notification settings - Fork 1.6k
USER FAQ
-
沙箱默认不支持JRE环境运行
-
沙箱当前的工作环境在1.4.0版本之前可以运行在JDK1.6+,1.4.0(包含)之后,最低运行环境要求JDK8。
-
由于实现上准守JVM虚拟机规范,所以openJDK和oracleJDK以及其他发行版均可正确运行。
-
1.4.0版本之后引入了native功能,由于功能实现的特殊性对JVM兼容性有一定的要求。当前经过稳定测试的JVM版本是[oracle/open]JDK-[8,12]
-
沙箱执行必须拥有可操作目标JVM的用户权限,最好是在相同的用户下进行
-
沙箱不推荐在linux/unix系统下用root账号运行。如果必须要求root账号运行,则需要自行对sandbox.sh脚本做适当修改
沙箱由纯Java实现,可以运行在任何支持JVM的操作系统下。对操作系统没有特殊要求。
-
什么是固有函数(intrinsic)?
固有函数大概相当于C++ 的宏或者inline函数, 即消去了函数调用过程的函数, 不过有的固有函数优化的更加极致,比如compareAndSwap的固有函数会将底层汇编原语直接内联。
-
对固有函数增强有什么问题?
很遗憾,因JVM的特性需要,固有函数的代码都是定死的,一旦JVM决定要对固有函数执行内联优化后,将会采用内部的代码完成现有字节码的替换(JIT),所以无法对已被内联的固有函数进行有效增强。
这个可以认为是JVM的特性而不是BUG。具体详见JDK-8013579
-
沙箱如何解决这个问题?
固有函数相比普通函数有将近130%的性能提升,可以参考这篇文章分析HotSpot Intrinsics,所以建议轻易不要直接全部关闭。
JVM开放了两个参数可以让我们针对某一个固有方法进行关闭,尽量减少性能损失的范围。
-
-XX:+UnlockDiagnosticVMOptions
解锁诊断模式,参数启用后将会解锁一系列参数用于JVM研发者的内部诊断。其中就包括我们接下来马上要用的
DisableIntrinsic
-
-XX:CompileCommand=dontinline,CLASS-NAME::METHOD-NAME(,...)
关闭C1对指定函数的inline优化
-
-XX:DisableIntrinsic=[INTRINSIC-ID]
禁用固有函数,每一个固有函数都有自己全局唯一ID,被定义在vmIntrinsics.hpp文件中,你需要根据实际增强的类和方法找到对应的
INTRINSIC-ID
如果你需要同时禁用多个
INTRINSIC-ID
,请用,
分隔。
-
-
一个典型的例子:JVM时间穿越
要实现JVM的时间穿越,就必须拦截并且按需修改
java.lang.System#currentTimeMillis()
方法的返回值,但这个方法是一个固有函数
,所以当你增强运行1分钟左右就会发现逐渐有一些调用拦截不到了。产生这个现象的原因就是这部分执行过程被JVM用固有函数进行了JIT替换,绕开了沙箱埋入的代码。此时你可以在目标JVM启动参数中增加以下参数,即可解决问题
-XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=dontinline,java.lang.System::currentTimeMillis -XX:DisableIntrinsic=_currentTimeMillis
JVM沙箱偏向于底层产品,受众面比较窄,问题反馈沟通很可能会因为各种原因造成不及时。所以我们建立了一个钉钉小群,方便大家在这里进行沟通。