Java GetStringCritical会导致死锁吗?

Java GetStringCritical会导致死锁吗?,java,android,java-native-interface,deadlock,Java,Android,Java Native Interface,Deadlock,system_服务器中发生死锁,锁由PackageManager持有 "PackageManager" prio=5 tid=27 WaitingForGcToComplete | group="main" sCount=1 dsCount=0 obj=0x12d3e7b0 self=0xb865c1a0 | sysTid=579 nice=0 cgrp=default sched=0/0 handle=0xb865c788 | state=S schedstat=( 8230098

system_服务器中发生死锁,锁由PackageManager持有

"PackageManager" prio=5 tid=27 WaitingForGcToComplete
  | group="main" sCount=1 dsCount=0 obj=0x12d3e7b0 self=0xb865c1a0
  | sysTid=579 nice=0 cgrp=default sched=0/0 handle=0xb865c788
  | state=S schedstat=( 82300981 68593861 146 ) utm=6 stm=2 core=1 HZ=100
  | stack=0xa0fdb000-0xa0fdd000 stackSize=1036KB
  | held mutexes=
  native: #00 pc 00012960  /system/lib/libc.so (syscall+28)
  native: #01 pc 000a88ad  /system/lib/libart.so(art::Mutex::ExclusiveLock(art::Thread*)+364)
  native: #02 pc 0013aa7b  /system/lib/libart.so (art::gc::Heap::IncrementDisableMovingGC(art::Thread*)+90)
  native: #03 pc 001c0329  /system/lib/libart.so (art::JNI::GetStringCritical(_JNIEnv*, _jstring*, unsigned char*)+392)
  native: #04 pc 00082223  /system/lib/libandroid_runtime.so (???)
  native: #05 pc 00082291  /system/lib/libandroid_runtime.so (???)
  native: #06 pc 00263595  /data/dalvik-cache/arm/system@framework@boot.oat (Java_android_os_Parcel_nativeWriteString__JLjava_lang_String_2+120)
  at android.os.Parcel.nativeWriteString(Native method)
  at android.os.Parcel.writeString(Parcel.java:542)
  at android.content.ComponentName.writeToParcel(ComponentName.java:267)
  at android.content.ComponentName.writeToParcel(ComponentName.java:282)
  at android.content.Intent.writeToParcel(Intent.java:7486)
  at android.app.ApplicationThreadProxy.scheduleUnbindService(ApplicationThreadNative.java:929)
  at com.android.server.am.ActiveServices.removeConnectionLocked(ActiveServices.java:1842)
  at com.android.server.am.ActiveServices.unbindServiceLocked(ActiveServices.java:943)
  at com.android.server.am.ActivityManagerService.unbindService(ActivityManagerService.java:15787)
  - locked <0x1d3e13e9> (a com.android.server.am.ActivityManagerService)
我不能确定死锁是由android_os_Parcel_writeString引起的,因为android_os_Parcel_writeString是一种非常常用的方法

所以我想问的是android操作系统是否会导致死锁


谢谢你的回答,忘了我笨拙的英语。

GetStringCritical
使用时必须格外小心。你必须 确保在持有通过
GetStringCritical
获得的指针时,本机代码不会在JVM中分配新对象或执行其他可能导致系统死锁的阻塞调用

    /* This is not safe! */
const char *c_str = (*env)->GetStringCritical(env, j_str, 0);
if (c_str == NULL) {
... /* error handling */
}
fprintf(fd, "%s\n", c_str);
(*env)->ReleaseStringCritical(env, j_str, c_str);
代码的问题是,写入文件并不总是安全的 当前线程禁用垃圾收集时的句柄。对于 例如,另一个
线程T
正在等待从
fd
文件句柄读取。让我们 进一步假设操作系统缓冲设置为
fprintf
调用将等待
线程T
完成从
fd
读取所有挂起的数据。我们 构建了死锁的可能场景:如果
线程T
无法分配 必须有足够的内存作为从文件句柄读取的缓冲区 请求垃圾回收。垃圾收集请求将被阻止,直到 当前线程执行
ReleaseStringCritical
,直到
fprintf
调用返回。然而,
fprintf
调用正在等待
线程T
完成从文件句柄的读取

查看后,方法
writeString16
是无死锁的。到目前为止,我从未发现包裹有任何问题

    /* This is not safe! */
const char *c_str = (*env)->GetStringCritical(env, j_str, 0);
if (c_str == NULL) {
... /* error handling */
}
fprintf(fd, "%s\n", c_str);
(*env)->ReleaseStringCritical(env, j_str, c_str);