JNI (java native interface)

JVM让线程进入到native状态,JVM就控制不了你在做啥了。

JNI与SafePoint

如果JVM需要对stack和heap做一些操作该怎么办呢? safepoint就是一个安全点,所有的线程执行到安全点的时候就会去检查是否需要执行safepoint操作,如果需要执行,那么所有的线程都将会等待,直到所有的线程进入safepoint。 然后使JVM可以安全的进行一些操作,比如开始GC,结束后所有的线程再恢复执行。 GC的标记阶段需要stop the world,让所有Java线程挂起,这样JVM才可以安全地来标记对象。safepoint可以用来实现让所有Java线程挂起的需求。这是一种”主动式”(Voluntary Suspension)的实现。JVM有两种执行方式:解释型和编译型(JIT),JVM要保证这两种执行方式下safepoint都能工作。 在JIT执行方式下,JIT编译的时候直接把safepoint的检查代码加入了生成的本地代码,当JVM需要让Java线程进入safepoint的时候,只需要设置一个标志位,让Java线程运行到safepoint的时候主动检查这个标志位,如果标志被设置,那么线程停顿,如果没有被设置,那么继续执行。

  • GC的同时可以执行JNI。
  • JNI返回时Java正在SafePoint。【如果线程再执行JNI代码的哪一个时刻,java线程也处于safepoint状态。因为java线程在执行本地代码之前,需要保存堆栈的状态,让后再移交给native方法。】

    safepoint主要特定位置-避免程序长时间运行而不进入safepoint

  1. 循环的末尾 (防止大循环的时候一直不进入safepoint,而其他线程在等待它进入safepoint)
    2. 方法返回前
    3. 调用方法的call之后
    4. 抛出异常的位置