Java|Java Agent 踩坑之 appendToSystemClassLoaderSearch 问题( 三 )


如果是 Java 程序 , 直接用 ThreadLoal 来存储 iconv_t 就能解决了 。
但是 cpp 这边 , 虽然 C++ 11 支持 thread_local , 但首先 jdk8 还没用 C++ 11(这个可以参考 JEP );其次 , C++ 11 的也仅仅支持 thread_local 的 set 和 get , thread_local 的初始化、销毁等生命周期管理还不支持 , 比如没办法在线程结束时自动回收 iconv_t 资源 。
那咱们就 fallback 到 pthread?因为 pthread 提供了 thread-specific data , 可以做类似的事情 。
















【Java|Java Agent 踩坑之 appendToSystemClassLoaderSearch 问题】
pthread_key_create 创建 thread-local storage 区域 pthread_setspecific 用于将值放入 thread-local storage pthread_getspecific 用于从 thread-local storage 取出值 最重要的 , pthread_once 满足了 pthread_key_t 只能初始化一次的需求 。另外也需要提到的 , pthread_once 的第二个参数 , 就是线程结束时的回调 , 我们就可以用它来关闭 iconv_t , 避免资源泄漏 。总之 pthread 提供了 thread_local 的全生命周期管理 。 于是 , 最终代码如下 , 用 make_key 初始化 thread-local storage: 于是编译 JDK 之后 , 打镜像、批量重启数次 pod , 就没有再出现文章开头提到的问题了 。总结 在整个过程中 , 从 Java 到 JNI/JVMTi , 再到 glibc , 再到 pthread , 踩了很多坑: printf 要加上 fflush 才能保证输出成功 环境变量会影响本地字符编码转换 iconv 不是线程安全的 使用 pthread thread-local storage 来实现线程局部变量的全生命周期管理 从这个案例中 , 沿着调用栈、代码 , 逐步还原问题、并提出解决方案 , 希望大家能对 Java/JVM 多了解一点 。参考链接: [1
文档: https://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_09.html [2
one-java-agent 修复的链接: https://github.com/alibaba/one-java-agent/issues/31 [3
dragonwell 修复的链接: https://github.com/alibaba/dragonwell8/pull/346 [4
one-java-agent 给大家带来了更加方便、无侵入的微服务治理方式: https://www.aliyun.com/product/aliware/mse 原文链接:http://click.aliyun.com/m/1000349066/ 本文为阿里云原创内容 , 未经允许不得转载 。