关于OpenJdk8中的RegisterThread和objc_registerThreadWithCollector代码拾遗 置顶!
注意: 本文对于技术原理的解释可能过于片面, 由于一些不了解的技术理解可能会有偏差. 本文仅当作是OpenJDK中此段代码变迁的一些原因的记录与补充.
代码引用处: OpenJDK8u , 其它版本代码可能会有差异:你也可以在知乎阅读此文: https://zhuanlan.zhihu.com/p/523280432
主引用地方
在JavaMain.c中有如下函数:
int JNICALL
JavaMain(void * _args)
{
JavaMainArgs *args = (JavaMainArgs *)_args;
int argc = args->argc;
char **argv = args->argv;
int mode = args->mode;
char *what = args->what;
InvocationFunctions ifn = args->ifn;
JavaVM *vm = 0;
JNIEnv *env = 0;
jclass mainClass = NULL;
jclass appClass = NULL; // actual application class being launched
jmethodID mainID;
jobjectArray mainArgs;
int ret = 0;
jlong start = 0, end = 0;
RegisterThread();
// ......
// ......
// ......
}
RegisterThread不同平台实现
不同平台的实现:
// MacOS
void
RegisterThread()
{
objc_registerThreadWithCollector();
}
// Solaris
void
RegisterThread()
{
// stubbed out for windows and *nixes.
}
// Windows
void
RegisterThread()
{
// stubbed out for windows and *nixes.
}
可以看到macos的实现有一特殊的调用. 而在windows等其它平台均是一个空函数. macos的实现里面调用了objc_registerThreadWithCollector; 这个函数是干嘛用的呢.
objc_registerThreadWithCollector 函数
一段sample
static void *threadproc(
void *param
) {
athread *p = (athread *)param;
/* Register this thread with the Objective-C garbage collector */
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
objc_registerThreadWithCollector();
#endif
p->result = p->function(p->context);
p->finished = 1;
return 0;
}
下面是另外一段sample: 来自于: JetBrains/jdk8u_jdk
/*
* Unwrap the arguments and re-run main()
*/
static void *apple_main (void *arg)
{
objc_registerThreadWithCollector();
if (main_fptr == NULL) {
main_fptr = (int (*)())dlsym(RTLD_DEFAULT, "main");
if (main_fptr == NULL) {
JLI_ReportErrorMessageSys("error locating main entrypoint\n");
exit(1);
}
}
struct NSAppArgs *args = (struct NSAppArgs *) arg;
exit(main_fptr(args->argc, args->argv));
}
主要是向垃圾回收器注册自己的线程.如果没有注册则会报错.
我们再看来一下这个函数的实现: objc_registerThreadWithCollector
以下代码来自于xcode 12
/Applications/Xcode12.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/objc/objc-auto.h
OBJC_GC_DEPRECATED("it does nothing")
static OBJC_INLINE void objc_registerThreadWithCollector() { }
OBJC_GC_DEPRECATED("it does nothing")
static OBJC_INLINE void objc_unregisterThreadWithCollector() { }
OBJC_GC_DEPRECATED("it does nothing")
static OBJC_INLINE void objc_assertRegisteredThreadWithCollector() { }
最新状态: 废弃
可以看到此段代码已经被标记为废弃. 原因是在 xCode8.2及以后废弃了此功能引用 - Thread.h Contains a call to deprecated function 'objc_registerThreadWithCollector()' #1753. 至于是什么原因.怎么废弃的. 目前不得而知:
Warning of deprecation comes from Xcode 8.2. Need to replace or remove.
这个时间线,结合其它的开源软件的一些bug修复log.如:libusb changelog
再结合XCODE的发布时间:
Xcode版本 XCode发售日期
xcode8.1 : 2016年10月28日
xcode8 beta: 2016年6月14日
xcode7.3.1: 2016年5月3日更新
xcode7.3: 2016年3月22日
xcode7.2 beta: 2015年10月30日
xcode7.1 beta: 2015年9月9日
作者:千叶飞雪
链接:https://www.jianshu.com/p/a9948e4611d5
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
那比较确定是XCODE 8.2 移除了此特征代码.至于是升级为不需要人工处理还是彻底废弃. 不知而知.有知道的大佬可以在评论中麻烦告知.
- http://cr.openjdk.java.net/~anthony/7u6-2-keepEnvVars-7131021.1/src/macosx/bin/java_md_macosx.c.sdiff.html
- iOS系统和XCode各版本发布日期
- 聊聊那些iOS内存管理的关键字
- OBJECTIVE--C内存管理基础
- [Objective-C]内存管理
- Objective-C内存管理教程和原理剖析(一)基本原理
- Objective-C的内存管理
- http://hg.openjdk.java.net/macosx-port/macosx-port/jdk/rev/496ad079b40a
- https://stackoverflow.com/questions/3648605/gc-on-unregistered-thread-in-a-core-midi-callback
- https://mikeash.com/tmp/Runtime%20API%20Tour.pdf
- https://github.com/cinder/Cinder/issues/1753
- libusb change log
- https://opensource.apple.com/source/objc4/objc4-551.1/runtime/objc-auto.h.auto.html
- https://cpp.hotexamples.com/examples/-/-/objc_registerThreadWithCollector/cpp-objc_registerthreadwithcollector-function-examples.html