Java GetStringCritical会导致死锁吗?
system_服务器中发生死锁,锁由PackageManager持有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
"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);