【发布时间】:2015-01-06 05:49:12
【问题描述】:
我正在编写一个简单的内存报告实用程序(在这种特殊情况下,不能使用现有工具)。我已经得到它来打印通过迭代ManagementFactory.getMemoryPoolMXBeans() 返回的所有内存池的最大值、提交和使用情况。这让我获得了三代堆内存(eden、survivor 和 old)、permgen 和“代码缓存”。
这些似乎都不是方法堆栈内存。最接近的似乎是“代码缓存”,但我已经读到这实际上是热点放置编译类的地方。
我之所以这么问,是因为我正试图找出无法创建新线程的 JBoss webapp 崩溃的原因。 http://www.mastertheboss.com/jboss-server/jboss-monitoring/how-to-solve-javalangoutofmemoryerror-unable-to-create-new-native-thread 建议这可能是由于堆栈内存不足,这是有道理的。问题是:我如何获取堆栈内存,以便检查?
【问题讨论】:
-
每个线程的栈内存都是一样的。这意味着您的内存设置会导致您可以拥有的线程数量有限。您可以监控您当前拥有的线程数。
-
@Thilo 等等,所以每个线程在创建时都分配了完整的堆栈大小?即使大部分堆栈空间未使用(堆栈上的帧数很少),所有内存都已分配且不可用于堆、permgen、操作系统本身等?
-
“堆栈内存” 不是一个单独的池,它只是普通的虚拟内存。要么你的虚拟内存用完了,要么达到了进程数限制 (
ulimit -u)。 -
问题仍然是“JVM 为线程堆栈使用了多少内存?”不管 Java 是否认为它是一个单独的池。
-
@Thilo 并非所有线程都具有相同的堆栈大小。具有自定义堆栈大小的线程 can be constructed。