如何解决需要您点亮iOS线程
我正在数据报套接字上的POC应用程序上工作,我在iOS上。这是一个简单的单屏幕应用程序,带有几个按钮。无论如何,我的问题是EDT线程,GC线程和我的IO线程之一。我的IO线程有一个绑定的数据报套接字,等待消息(recvfrom)。有时,我发现EDT卡住了,而当我查看iOS线程堆栈时,我发现:
1-EDT线程正在睡眠,等待布尔值变为假
while(threadStateData->threadBlockedByGC) {
usleep(1000);
}
#3 0x0000000100e6ed02 in java_lang_Thread_sleep___long at /dist/MyApplication-src/nativeMethods.m:1231
#4 0x0000000101194c44 in java_lang_System_gc__ at /dist/MyApplication-src/java_lang_System.m:257
#5 0x0000000100c431c1 in codenameOneGcMalloc at /dist/MyApplication-src/cn1_globals.m:791
#6 0x00000001011bac4a in __NEW_com_codename1_ui_Label_1 at /dist/MyApplication-src/com_codename1_ui_Label_1.m:31
#7 0x0000000101491019 in com_codename1_ui_Label___INIT_____java_lang_String_java_lang_String at /dist/MyApplication-src/com_codename1_ui_Label.m:1402
...
2-GC线程也处于睡眠状态,等待另一个布尔值变为真
while(t->threadActive) {
usleep(500);
#3 0x0000000100c428d6 in codenameOneGCMark at /dist/MyApplication-src/cn1_globals.m:426
#4 0x0000000100e6e950 in java_lang_System_gcMarkSweep__ at /dist/MyApplication-src/nativeMethods.m:1078
#5 0x000000010119521d in java_lang_System_access$200__ at /dist/MyApplication-src/java_lang_System.m:331
...
A quick watch on t shows the threadId=8
t ThreadLocalData * 0x600001616eb0 0x0000600001616eb0
threadId JAVA_LONG 8
3-我的IO线程似乎是ID为8的线程(内存中的地址也相同)
A quick watch on threadStateData shows the threadId=8
threadStateData ThreadLocalData * 0x600001616eb0 0x0000600001616eb0
threadId JAVA_LONG 8
ssize_t result = recvfrom(socketDescriptor,buffer,sob,(struct sockaddr *)&receiveSockaddr,&receiveSockaddrLen);
#1 0x0000000101100a00 in -[net_etc_net_impl_NativeDatagramSocketImpl receive:param1:param2:param3:] at /dist/MyApplication-src/net_et_net_impl_NativeDatagramSocketImpl.m:131
#2 0x0000000101615f6b in net_etc_net_impl_NativeDatagramSocketImplCodenameOne_receive___int_int_java_lang_String_int_R_int at /dist/MyApplication-src/native_net_et_net_impl_NativeDatagramSocketImplCodenameOne.m:51
#3 0x0000000100f7fc9e in net_etc_net_impl_NativeDatagramSocketStub_receive___int_int_java_lang_String_int_R_int at /dist/MyApplication-src/net_etc_net_impl_NativeDatagramSocketStub.m:87
#4 0x0000000100d59939 in virtual_net_etc_net_impl_NativeDatagramSocket_receive___int_int_java_lang_String_int_R_int at /dist/MyApplication-src/net_etc_net_impl_NativeDatagramSocket.m:91
#5 0x000000010156690f in net_etc_net_DatagramSocket_receive___byte_1ARRAY_int_R_int at /dist/MyApplication-src/net_etceterum_net_DatagramSocket.m:215
所以我的问题是:我该怎么做才能防止这种情况?
感谢您的帮助。
以马内利
解决方法
请参阅我们套接字实现中的this code。我建议在代码中添加yield / resume调用,以使GC正常工作。只要确保您在这段时间内不做任何基于Java的分配即可。
这是怎么回事:
- GC需要运行,因此它会在所有活动线程上循环并尝试收集
- 您的线程从Java端开始,因此被标记为GC线程
- 它被标记为活着的
- GC希望它暂停分配,以便可以GC
- 线程没有意识到这一点,因为它在C代码中使用了很长时间……死锁
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。