是否可以计算每个线程的内存消耗?假设我将我的任务分成4个线程,然后我想知道每个线程消耗了多少内存?我需要它来了解我的线程的平均和峰值内存使用情况。
发布于 2021-04-13 13:50:00
正如其他人指出的那样,大多数对象都存在于heap上。该堆内存在线程之间共享。因此,没有办法确定哪些线程对堆的大小负责。
但是线程确实有自己的内存块:堆栈。
堆栈大小
我记得甲骨文的Ron Pressler在2020…的演讲
常规线程
为每个线程分配一定数量的内存用于其stack。由于目前基于OpenJDK的Java实现中的线程是一对一地映射到宿主操作系统的线程,因此堆栈大小被任意设置为类似于meg的值。如果需要,可以分配更多的内存,但不会减少。
虚拟线程
随着虚拟线程的出现,情况变得更加复杂( 中提出的fibers。
Project Loom向Java并发工具添加了新功能。作为其中的一部分,虚拟线程被多对一地映射到主机操作系统线程(也称为平台/内核线程)。JVM将管理这些虚拟线程,而不是OS,当虚拟线程的代码阻塞时,它会“驻留”虚拟线程,以便有时间让另一个虚拟线程通过分配给“真实”平台/内核线程的执行时间来运行。无论有没有Project Loom (至少在基于的Java实现中),“真正的”平台/内核线程在CPU核心上实际完成工作的调度都是由主机操作系统控制的。
➥作为虚拟线程的JVM管理的一部分,每个虚拟线程的堆栈将从更小的堆栈开始。每个堆栈都会根据需要增长和收缩(!)。
由于CPU和内存的有效利用,虚拟线程大大“便宜”了。这样我们就可以运行更多的程序。甚至数百万个虚拟线程在普通硬件上也是可能的。
发布于 2021-04-13 13:21:11
总结我的评论,线程使用共享内存。因此,除了保留的堆栈内存(这是在jvm启动时设置的)之外,没有线程拥有自己的任何数据。
由于您关注的是线程在运行jvm时消耗的确切堆大小,因此您可以简单地使用诸如visualvm之类的内存分析器来查看线程创建的类和对象,并假定消耗大小。
您还可以使用ThreadLocal变量来定义属于特定线程的对象。这还可以帮助您在每个线程的基础上获得准确的内存消耗。
您还可以查看ThreadMXBean,但是在最新的jvm中不再提供此功能。
https://stackoverflow.com/questions/67068623
复制相似问题