2013-05-06 91 views
1

我有一个Java/Java EE Web应用程序。Java Web应用程序:高堆使用和被阻塞的线程 - 同时

通常,当我看到应用程序由于堆使用率高(或内存不足情况)而停止响应时,我还会看到线程被阻塞(通过线程转储) - 通常是记录和随机事件。

我在Web应用程序中看到过这种情况。

内存不足情况与被阻塞的线程之间是否存在任何关联?

回答

1

是的,OOM和被阻塞的线程之间有直接的相关性。这是由于线程试图在堆上分配内存并且无法获得足够的内存。大多数情况下,您会在日志,类加载,资源查找,IO等方面看到阻塞的线程。这些都是需要新内存分配的情况。

0

是的,存在相关性。虽然线程共享堆但他们有自己的堆栈。两者都是从可用内存分配的内存。一个线程可能正在做一些工作,正如你在案例日志中提到的那样。对于日志记录线程可能会在内存中保留一些日志,并将尝试将它们放入日志文件中。由于存在不同的日志记录线程,因此他们将等待轮到获得日志文件的访问权限。如果线程等待文件的时间太长,那么他们会将日志数据保存在内存中很长时间。如果这种情况持续发生,那么内存中数据太多的线程就会太多。当有人试图获得内存并且没有任何可用时,JVM最终会遇到内存不足的情况。

1

是的,因为线程是你的代码执行的地方,你的代码需要内存。 Java是面向对象的,因此创建新对象是非常普遍的事情。当JVM遇到内存问题时,尝试分配更多的内存块,直到可以授予内存为止。与外部系统(I/O)的接口是看到线程阻塞的共同点,因为它们通常涉及大量的内存分配块(例如用于格式化的字符串缓冲区,由类加载程序在.class文件中读取,为数据库结果集生成对象)。

这是为什么排除OutOfMemoryError非常困难的原因之一。当您的堆空间耗尽/耗尽时,每件事情都会放慢速度并突破,从而将症状与原因分离变得困难。