Skip to content

USER FAQ

oldmanpushcart@gmail.com edited this page Jan 28, 2023 · 2 revisions

BANNER

常见问题

沙箱运行环境对JDK的要求

  1. 沙箱默认不支持JRE环境运行

  2. 沙箱当前的工作环境在1.4.0版本之前可以运行在JDK1.6+,1.4.0(包含)之后,最低运行环境要求JDK8。

  3. 由于实现上准守JVM虚拟机规范,所以openJDK和oracleJDK以及其他发行版均可正确运行。

  4. 1.4.0版本之后引入了native功能,由于功能实现的特殊性对JVM兼容性有一定的要求。当前经过稳定测试的JVM版本是[oracle/open]JDK-[8,12]

沙箱运行环境对用户权限的要求

  1. 沙箱执行必须拥有可操作目标JVM的用户权限,最好是在相同的用户下进行

  2. 沙箱不推荐在linux/unix系统下用root账号运行。如果必须要求root账号运行,则需要自行对sandbox.sh脚本做适当修改

沙箱运行环境对操作系统的要求

沙箱由纯Java实现,可以运行在任何支持JVM的操作系统下。对操作系统没有特殊要求。

沙箱如何增强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

LOGO

JVM沙箱偏向于底层产品,受众面比较窄,问题反馈沟通很可能会因为各种原因造成不及时。所以我们建立了一个钉钉小群,方便大家在这里进行沟通。

Clone this wiki locally