Java 为什么JNI活动实例会阻止GC? bool PSScavenge::invoke_no_policy()
如您所见,如果Java 为什么JNI活动实例会阻止GC? bool PSScavenge::invoke_no_policy(),java,garbage-collection,jvm,jvm-hotspot,Java,Garbage Collection,Jvm,Jvm Hotspot,如您所见,如果GCLocker::check\u active\u before\u gc()为true,则它不会调用次要gc,即PSScavenge::invoke\u no\u policy()。为什么 检查\u gc()之前的\u活动\u _是否处于活动状态() 是否处于活动状态\u内部() _jni\u锁\u计数 \u jni\u lock\u count跟踪正在运行的线程数 目前在一个关键地区 \u jni\u lock\u count跟踪当前处于关键区域的线程数 如前所述,JNI关键
GCLocker::check\u active\u before\u gc()
为true
,则它不会调用次要gc,即PSScavenge::invoke\u no\u policy()
。为什么
检查\u gc()之前的\u活动\u
_是否处于活动状态()
是否处于活动状态\u内部()
_jni\u锁\u计数
\u jni\u lock\u count
跟踪正在运行的线程数
目前在一个关键地区
\u jni\u lock\u count
跟踪当前处于关键区域的线程数
如前所述,JNI关键函数暂时禁用垃圾收集
调用GetPrimitiveArrayCritical后,本机代码不应
在调用之前运行一段较长的时间
ReleasePrimitiveArrayCritical。我们必须处理这一对中的代码
在“关键区域”中运行的函数。在关键区域中运行
区域,本机代码不得调用其他JNI函数或任何系统
可能导致当前线程阻塞并等待另一个线程的调用
Java线程。(例如,当前线程不能在
流正在由另一个Java线程写入。)
这些限制使本机代码更有可能
获取阵列的未复制版本,即使VM没有
支持钉扎。例如,VM可能会暂时禁用垃圾
当本机代码持有指向数组的指针时
通过GetPrimitiveArrayCritical获取
...
if (GCLocker::check_active_before_gc()) {
return false;
}
...
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();
}
// Accessors
static bool is_active() {
assert(SafepointSynchronize::is_at_safepoint(), "only read at safepoint");
return is_active_internal();
}
static bool is_active_internal() {
verify_critical_count();
return _jni_lock_count > 0;
}
static volatile jint _jni_lock_count; // number of jni active instances.