问题
ThreadPoolExecutor
中BlockingQueue
队列中的任务是什么?- 一个任务占用的内存大小?
分析
参考 4 种方法教你如何查看 java 对象所占内存大小,编写如下代码进行测试。
POM 依赖:
<!-- 估计内存占用 -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>9.3.0</version>
</dependency>
<!-- JOL(Java Object Layout,Java 对象内存布局) -->
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.16</version>
</dependency>
Java 代码:
/**
* 查看对象占用内存大小
*
* @author ageovb
* @date 22/09/06 19:49
*/
public class SizeofObject {
public static void main(String[] args) {
// 定义一个线程,查看内存占用
Runnable t1 = new Thread(() -> System.out.println("Thread t1 "));
// JOL(Java Object Layout,Java 对象内存布局)
System.out.println("ClassLayout.parseInstance: " + ClassLayout.parseInstance(t1).toPrintable());
// Shallow Size = [类定义] + 父类fields所占空间 + 自身fields所占空间 + [alignment]
System.out.println("RamUsageEstimator.shallowSizeOf: " + RamUsageEstimator.shallowSizeOf(t1));
// Retained Size(JVM 概念) 是指,当实例 A 被回收时,可以同时被回收的实例的 Shallow Size 之和
System.out.println("RamUsageEstimator.sizeOfObject: " + RamUsageEstimator.sizeOfObject(t1));
System.out.println();
// 定义线程池,为了使阻塞队列中有任务,核心线程数和最大线程数都设置为 1
LinkedBlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
ThreadPoolExecutor executor = new ThreadPoolExecutor(
1, 1, 1000L, TimeUnit.SECONDS, workQueue);
for (int i = 0; i < 3; i++) {
// 打印阻塞队列长度及占用内存大小
executor.execute(() -> System.out.println("workQueue size: " + executor.getQueue().size() +
", bytes: " + RamUsageEstimator.sizeOfObject(executor.getQueue())));
}
}
}
打印日志如下:
ClassLayout
分析的内存占用比 RamUsageEstimator
小一点,暂时采用 RamUsageEstimator
分析的结果。
结论
对于问题一,ThreadPoolExecutor
中 BlockingQueue
队列中的任务是 Runnable
对象的实例,即 Thread
对象。
对于问题二,一个任务,即 Thread
对象占用 256 Byte。