我在具有 192 GB RAM 的 Linux 服务器中运行 Java (TIBCO EBX),我们不断看到 Java 进程重新启动,应用程序将进入挂起状态,并出现内存不足警报。我们将堆大小设置为 176 GB,我们看到堆大小在 10 小时的间隔后变满,而内存利用率从未下降。如果我们重新启动服务器,内存利用率将会下降。我们尝试获取服务器的 Kdump 来分析内存泄漏,在 vmcore-dmesg.txt 中,我们看到以下条目。谁能建议这是否导致我们的内存泄漏以及我们如何解决这个问题?
[ 389.832835] SysRq : Trigger a crash
[ 390.049124] BUG: unable to handle kernel NULL pointer dereference at (null)
[ 390.050076] IP: [<ffffffffbb270326>] sysrq_handle_crash+0x16/0x20
[ 390.050076] PGD 80000017c6c6e067 PUD 17fa9c8067 PMD 0
我们的内核版本如下:-
$uname -r
3.10.0-1062.52.2.el7.x86_64
$ uname -a
Linux sr001 3.10.0-1062.52.2.el7.x86_64 #1 SMP Thu Jul 8 09:03:01 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
任何其他建议/建议都可以看看。
内核 dmesg 消息是通过 SysRq 机制故意触发崩溃的结果(使用神奇的 SysRq 组合键 Alt-SysRq 后跟
c
,或者将 c
写入“/proc/sysrq-trigger”文件)。 (这些需要在内核中启用 SysRq 机制。)它们与内存泄漏无关。
当 SysRq 机制触发内核崩溃时,“drivers/tty/sysrq.c”中的
sysrq_handle_crash()
函数(自内核 2.6.37 起)。对于3.10内核,其函数定义如下:
static void sysrq_handle_crash(int key)
{
char *killer = NULL;
panic_on_oops = 1; /* force panic */
wmb();
*killer = 1;
}
该
*killer = 1;
行触发了导致内核恐慌的错误。但这并不是真正的错误,因为它是故意这样做的。
毫无疑问,
BUG:
的消息会让一些人感到震惊。在内核5.0中,函数被更改以避免故意空指针取消引用,直接调用panic()
,如下:
static void sysrq_handle_crash(int key)
{
/* release the RCU read lock before crashing */
rcu_read_unlock();
panic("sysrq triggered crash\n");
}
(之所以存在
rcu_read_unlock()
调用,是因为在调用此函数之前调用了 rcu_read_lock()
。)
我怀疑内存泄漏可能是在应用程序中而不是在内核中。一种判断方法是终止该应用程序。如果内存泄漏发生在应用程序中,则当其进程被终止时,内存使用应该恢复正常。如果内存泄漏发生在内核中,则在内核重新启动之前,内存将无法进一步使用。
您尚未指定您使用的是 TIBCO EBX 版本 5.x 还是 6.x 。但假设您使用的是版本 6.x ,则可能由多种原因导致:
您还可以使用 VisualVM 等任何分析器(有助于拍摄应用程序进程的快照/线程转储)来检查是否有任何进程消耗过多的 CPU。
如果这没有帮助,您可以联系 TIBCO 支持。