如何以编程方式获取堆栈内存统计信息?
Posted
技术标签:
【中文标题】如何以编程方式获取堆栈内存统计信息?【英文标题】:How do I get stack memory stats programatically? 【发布时间】: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。
【参考方案1】:
在 Linux 上,您可以解析 /proc/self/maps
(或 /proc/self/smaps
了解更多详细信息)。
查找以[stack:NNN]
结尾的行并将堆栈大小计算为top
- bottom
:
7f8a5c0e1000-7f8a5c1df000 rw-p 00000000 00:00 0 [stack:2669]
^ bottom ^ top ^ tid
在 Windows 上这会更难,但您可以将堆栈使用的内存估计为number_of_threads * default_stack_size
【讨论】:
以上是关于如何以编程方式获取堆栈内存统计信息?的主要内容,如果未能解决你的问题,请参考以下文章
在c#中以编程方式查询网卡的入站/出站IPv4数据包计数统计