当前位置: 首页 > 知识库问答 >
问题:

ThreadMXBean#getThreadAllocatedBytes会返回已分配内存或对象的大小吗?

融伯寅
2023-03-14

我想雇用com。太阳经营ThreadMXBean执行以下操作:

long before = threadMxBean.getThreadAllocatedBytes(currentThreadId);
seriousBusiness(); // some calls here
long after = threadMxBean.getThreadAllocatedBytes(currentThreadId);
long allocDiff = after - before; // use for stats or whatever

问题是,这个方法实际上返回了什么:在方法调用时分配的新内存量或分配对象的大小?为了清楚我的意思是什么区别:

1)假设我在我的serousBusiness()调用中分配了一个巨大的数组,因此为此分配了一个新的内存区域,并且getThreadAllocatedBytes增加了相应的值。

2) 一段时间过去了,有一次GC运行,收集了未使用的数组,内存区域现在是空闲的。

3) 我再次执行一些调用(在同一个线程中),JVM发现它不需要分配新内存,并为新的目的重用该内存区域,这导致值没有增长。

我可能不太清楚JVM内存管理是如何工作的,但问题应该很清楚。

此外,如果第一个假设是正确的(只是新的内存分配计数),那么执行线程对象分配/内存占用测量的正确方法是什么?

UPD。我试着自己检查:http://pastebin.com/ECQpz8g4.(代码中的睡眠是为了允许我用JMC连接到JVM)。

太长别读:分配一个巨大的int数组,然后GC它,然后分配一些新对象并检查分配的内存。这是我得到的:

665328          // before everything started
4295684088      // 4 GiB allocated
4295684296      // did GC (for certain! (really?))
5812441672      // allocated a long string, took new memory

所以,我只是在等待一个在JVM内存方面有专业知识的人告诉我我是对的还是错在哪里。

共有2个答案

沙富
2023-03-14

ThreadMXBean.getThreadAllocatedBytes返回给定线程从一开始分配的堆内存的累积量,即这是一个单调递增的计数器。它大致是分配对象的总大小。

编辑

热点JVM中分配的堆内存没有“线程所有权”。一旦分配了内存,它将在所有线程之间共享。所以,“每线程使用率”并没有真正意义;当JVM在堆中分配一个对象时,它不知道这个内存之前是否被谁使用过。

微生鸿轩
2023-03-14

引用ThreadMXBean,它代表目标线程报告堆中分配的字节数,但暗示这相当于分配的对象的大小。不过有一个警告:

返回的值是近似值,因为某些Java虚拟机实现可能使用对象分配机制,这会导致分配对象的时间与记录对象大小的时间之间的延迟

因此,我假设堆空间的回收对报告的值没有影响,因为它只报告分配的字节的绝对数,因此如果分配100个字节,则回收80个字节,然后再分配100个字节,则在这些事件结束时报告的(增量)值将为200个字节,尽管净分配只有120个字节。

 类似资料:
  • 在我的应用程序中,我有一个单一的活动架构,我为每个片段定义了一个“视图”类。 这个“视图”类包含视图状态和视图操作,它们引用视图的数据和操作。 例如,我有一个“MainFragment.kt”和一个相关的“MainView.kt”文件,它是这样的: 然后导入“主状态”和“操作”,并在“主状态ragment.kt”及其“视图模型”类中使用。 正如您所见,“MainView”被定义为一个对象,因为我不

  • 在我的计算机科学课程中,我们被教导说,当你创建一个数组时,JVM会根据数组的大小自动分配内存。例如,如果您创建一个大小为10的整数数组,JVM会为该数组分配10*32位数据。 我的问题是,当您创建大小不同的对象数组时,这个过程到底是如何工作的?例如一个字符串对象。当您创建一个由10个字符串组成的数组时,系统上是否实际为这些字符串保留了任何内存,或者因为它们只是指针,所以不需要分配内存?

  • jvm的对象头是如何存储的? 对象头中有哪些信息? 对象头里面的东西:运行时元数据,类型指针:Hashcode,GC分代年龄,锁状态标志,线程持有的锁,偏向线程ID,偏向时间戳。如果是数组的化还需要记录长度 就比如下面的代码来看,内存分布情况: 由于是static的main方法所有局部变量表没有this,如果是非静态方法的话第一个放this。 其次: 栈帧:局部变量表,操作数栈,动态链接,方法返回

  • 问题内容: 长话短说,我想针对该类测试android.os.Bundle类的克隆实现,以查看哪种更好。我已经知道我的版本很可能会更糟糕,但我想知道 有多少 糟糕。是否有适用于Android的基准测试工具,可以用来查看哪个对象的内存更大和/或需要更多的处理时间来存储/检索值? TL; DR: 我查看了android.os.Bundle类的源代码,但我不喜欢它存储和返回对象的方式。它只是将它们存储在中

  • 我似乎对这段代码有问题,我试图使用mysqli_connect()和mysqli_query()查询数据库,但代码没有返回mysqli对象,我不知道为什么。我自己编写了代码来格式化查询,我确信没有失败,因为我每次都在检查:(我使用XAMPP,使用localhost进行测试),可能是安装的php已经损坏了吗??) 我用这里的代码来测试:mysqli_query()返回的不是false,而是mysql

  • 最近我一直在阅读Java不同世代的对象分配。大多数时候,新对象在伊甸园(年轻一代的一部分)中分配,然后如果满足以下任何标准,它们就会晋升为老一代。 (1) 当从伊甸园(或)另一个幸存者空间(从)复制对象时,对象的年龄已达到寿命阈值 (2)幸存者空间(到)已满 但是也有一种特殊情况,即对象直接在旧一代中分配,而不是从年轻一代中提升。当我们试图创建的对象很大(可能是几个MB的数量级)时,就会发生这种情