如何以编程方式获取堆栈内存统计信息?

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

【讨论】:

以上是关于如何以编程方式获取堆栈内存统计信息?的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式访问 MacOS 系统性能统计信息

在c#中以编程方式查询网卡的入站/出站IPv4数据包计数统计

Mac OS X 中的每个进程磁盘读/写统计信息

iphone inapp购买编程?如何从苹果获取统计信息

以编程方式更改 PDS 成员的 ISPF 统计信息中的用户 ID

如何使用 node.js 获取系统统计信息