2010-08-19 26 views
2

在Solaris x86上的32位jvm上运行Java EE应用程序时,出现OutOfMemoryError:无法创建本机线程(或类似的东西)。
这是因为根据我的理解,jvm没有足够的内存用于新线程的堆栈。如何监视内存的Java线程堆栈

我使用JConsole和VisualVM 1.3来监视应用程序,但我不知道在这些工具中调用“stackmemory”是什么。在VisualVM中,我可以监视heappace和permgen空间,而JConsole显示更多的内存区域。这些内存区域是否被预留用于堆栈内存?我知道这不是堆空间,但是如何处理permgen或non-heap(如JConsole中所述)

+1

机器是否有足够的交换? – 2010-08-19 09:24:57

+0

$>交换-s 合计:1609736k字节分配+ 760644k保留= 2370380k使用,57741028k可用。 我已经将heapsize设置为3072m,因此jvm应该可以在理论上使用另一个1024mb的非堆空间(实际上我猜测的数量少一些) – Ola 2010-08-19 09:56:23

回答

0

您也可以尝试JProfiler。 在JProfiler中,您可以从CPU概览视图中的线程视图和线程状态中获得提示。这里是screencast

您还可以检查以下来调试您的问题:(链接引用)如果遇到此异常,有几件事要做。

  • 使用lsof -p PID命令(在Unix平台 ),看 多少线程是活动的这个过程。
  • 确定操作系统定义的 每个进程的最大线程数是否有最大值 。如果限制 对应用程序而言太低,请尝试 以提高每个进程的线程限制。
  • 检查应用程序代码为 确定是否存在创建线程或连接(如 作为LDAP连接)的代码,而不是 将其销毁。您可以转储 Java线程以查看是否存在已创建过多数量的 。
  • 如果您发现 由应用程序打开过多的连接,让 确保任何线程的 应用程序创建被破坏。一个 企业应用程序(.ear)或Web 应用程序(.war)运行在长期运行的JVM的 之下。仅仅因为 应用程序已完成并不意味着JVM进程结束的 。它是 迫切需要一个应用程序免费分配的任何资源 。 另一种解决方案是为 应用程序使用线程池来 管理所需的线程。

您的代码的某些部分可能会创建大量的线程。

尝试在代码中使用ThreadPoolExecutor(线程池)来限制应用程序中的线程,并相应地调整线程池大小以获得更好的性能。