Keywords: JNI, Java, GC Thread, add_workers, static library, Thread Error
Solution: -XX:+AdjustStackSizeForTLS
from JDK 14
Description
We cannot launch GC thread of JVM from JNI. And, it shows
|
|
The main reason is the glibc bugs for native C code issues. For example, we allocate thread-local variables by static library linking.
|
|
And then, glibc 2.12 will move them on stack, and require minimum stack size at least 1024k bytes. But, the default configuration JVM of JDK11 will minimum stacksize to be 1024k bytes as default in Linux OS. Therefore, the pthread_create
throws the error EINVAL
for specific stacksize setting.
Options
https://www.oracle.com/java/technologies/javase/14all-relnotes.html
The glibc library allocates some thread-local storage (TLS) in the stack of a newly created thread, leaving less stack than requested for the thread to do its work. This is particularly a problem for threads with small stack sizes. It is an inherited issue from a well-known glibc problem, ‘Program with large TLS segments fail’ [0] and has been observed in Java applications. In one of the reported JVM failure instances, the issue manifests as a StackOverflowError on the process reaper thread, which has a small stack size. The java.lang.Thread constructor enables users to specify the stack size for a new thread. The created thread may encounter the TLS problem when the specified size is too small to accommodate the on-stack TLS blocks.
In JDK 8, a system property, jdk.lang.processReaperUseDefaultStackSize
, was introduced to address the TLS issue only for reaper threads. Setting the property gives a bigger stack size to the reaper threads.
To address the issue for all threads, a general purpose workaround was implemented in Java which adjusts thread stack size for TLS. It can be enabled by using the AdjustStackSizeForTLS
command-line option:
When creating a new thread, if AdjustStackSizeForTLS
is true, the static TLS area size is added to the user requested stack size. AdjustStackSizeForTLS
is disabled by default.
Conclusion
整合進大型程式時,要多觀察靜態編譯的部分,如果有一些 TLS 的宣告,則會增加其他預設執行緒的最小使用堆疊大小。而 JVM 又傾向使用最少資源去完成,則很容易在計算最小資源時發生問題。
如果去查閱 JDK15 的 代碼 os_linux.cpp 時,有一段到動態鏈結函數庫 glibc 的詢問最低需求來解決此問題。這一段牽涉到 hack 技巧,偷偷利用 symbol 爬出私有函數,不算正常操作行為。
|
|