SUGGESTED FIX
In os_linux_i486.cpp: (the same change is also needed in os_linux_amd64.cpp
and os_linux_ia64.cpp)
*** 563,581 ****
// may return bogus value.
*bottom = os::Linux::initial_thread_stack_bottom();
*size = os::Linux::initial_thread_stack_size();
} else {
pthread_attr_t attr;
int rslt = pthread_getattr_np(pthread_self(), &attr);
! guarantee(rslt == 0, "pthread_getattr_np must work");
void * top;
if (pthread_attr_getstackaddr(&attr, &top) != 0 ||
pthread_attr_getstacksize(&attr, size) != 0) {
fatal("Can not locate current stack attributes!");
}
*bottom = (address) align_size_up((uintptr_t)top - *size, os::Linux::page_size());
*size = (address)top - *bottom;
}
assert(os::current_stack_pointer() >= *bottom &&
os::current_stack_pointer() < *bottom + *size, "just checking");
--- 563,593 ----
// may return bogus value.
*bottom = os::Linux::initial_thread_stack_bottom();
*size = os::Linux::initial_thread_stack_size();
} else {
pthread_attr_t attr;
+ pthread_attr_init(&attr);
+
int rslt = pthread_getattr_np(pthread_self(), &attr);
!
! // JVM needs to know exact stack location, abort if it fails
! if (rslt != 0) {
! if (rslt == ENOMEM) {
! vm_exit_out_of_memory(0, "pthread_getattr_np");
! } else {
! fatal1("pthread_getattr_np failed with errno = %d", rslt);
! }
! }
void * top;
if (pthread_attr_getstackaddr(&attr, &top) != 0 ||
pthread_attr_getstacksize(&attr, size) != 0) {
fatal("Can not locate current stack attributes!");
}
+ pthread_attr_destroy(&attr);
+
*bottom = (address) align_size_up((uintptr_t)top - *size, os::Linux::page_size());
*size = (address)top - *bottom;
}
assert(os::current_stack_pointer() >= *bottom &&
os::current_stack_pointer() < *bottom + *size, "just checking");
|
EVALUATION
The errorid points to os_linux_i486.cpp, 774; further investigation shows
that a pthread_getattr_np() call just failed with ENOMEM. JVM relies on
pthread_getattr_np(), so it has no choice but to abort if the call fails.
Starting from Redhat AS-3 (NPTL-0.60 and later), pthread_getattr_np() will
allocate memory through malloc(), the memory is freed by pthread_attr_destroy().
In JVM, we didn't call pthread_attr_destroy() after pthread_getattr_np(), this
causes a small memory leak whenever pthread_getattr_np() is called (it is
called during thread creation).
In a long running application, especially when it has created lots of
threads, the memory leaks could add up and cause an out-of-memory error.
A temporary workaround is to disable NPTL by setting LD_ASSUME_KERNEL to
2.4.1.
###@###.### 2003-12-04
Fix is to call pthread_attr_destroy() after pthread_getattr_np(). It has
been verified with 1.4.2_02 JDK.
###@###.### 2003-12-08
Also I've been told that the issue has been fixed on the libc side too. It
will be available in the first update RHEL3 U1.
###@###.### 2003-12-08
|