【问题标题】:Why do JNI active instances prevent GC?为什么 JNI 活动实例会阻止 GC?
【发布时间】:2017-12-15 16:41:22
【问题描述】:

bool PSScavenge::invoke_no_policy()

  ...
  if (GCLocker::check_active_before_gc()) {
    return false;
  }
  ...

如你所见,如果GCLocker::check_active_before_gc()true,它不会调用minor GC,即PSScavenge::invoke_no_policy()。为什么会这样?

check_active_before_gc()

bool GCLocker::check_active_before_gc() {
  assert(SafepointSynchronize::is_at_safepoint(), "only read at safepoint");
  if (is_active() && !_needs_gc) {
    verify_critical_count();
    _needs_gc = true;
    log_debug_jni("Setting _needs_gc.");
  }
  return is_active();
}

is_active()

  // Accessors
  static bool is_active() {
    assert(SafepointSynchronize::is_at_safepoint(), "only read at safepoint");
    return is_active_internal();
  }

is_active_internal()

  static bool is_active_internal() {
    verify_critical_count();
    return _jni_lock_count > 0;
  }

_jni_lock_count

static volatile jint _jni_lock_count;  // number of jni active instances.

_jni_lock_count 跟踪正在运行的线程数 目前处于关键区域。

【问题讨论】:

    标签: java garbage-collection jvm jvm-hotspot


    【解决方案1】:

    _jni_lock_count 跟踪当前处于临界区的线程数。

    作为suggested by JNI specification,JNI 关键函数暂时禁用垃圾收集。

    调用 GetPrimitiveArrayCritical 后,本机代码不应 在它调用之前运行很长一段时间 ReleasePrimitiveArrayCritical。我们必须处理这对中的代码 在“关键区域”中运行的功能。 在关键的内部 区域,本机代码不得调用其他 JNI 函数或任何系统 可能导致当前线程阻塞并等待另一个线程的调用 Java 线程。 (例如,当前线程不能在一个 流由另一个 Java 线程编写。)

    这些限制使本机代码更有可能 获取阵列的未复制版本,即使 VM 没有 支持钉住。例如,VM 可能会暂时禁用垃圾 当本机代码持有指向数组的指针时,集合 通过 GetPrimitiveArrayCritical 获得。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-02-22
      • 1970-01-01
      • 2013-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-07
      相关资源
      最近更新 更多