为什么getThreadAllocatedBytes不一致?

时间:2015-07-10 10:25:54

标签: java memory runtime

我有JavaSpecialists newsletter这个方法threadAllocatedBytes()  它调出了ManagementFactory类

import java.lang.management.ManagementFactory;
import java.util.Arrays;

import javax.management.ObjectName;

public class MemoryTest {

    public static void main(String[] args) {
        for (int i = 0; i < 10; ++i)
            testMemory(i);
    }

    private static void testMemory(int nChars) {
        long bytes = threadAllocatedBytes();
        char[] test = new char[nChars];
        long bytes2 = threadAllocatedBytes();
        System.out.println("diff[" + +(nChars + 1) + "] = " + (bytes2 - bytes));
    }

    public static long threadAllocatedBytes() {
        try {
            return (Long) ManagementFactory.getPlatformMBeanServer().invoke(
                    new ObjectName(ManagementFactory.THREAD_MXBEAN_NAME), "getThreadAllocatedBytes",
                    new Object[] { Thread.currentThread().getId() }, new String[] { long.class.getName() });
        } catch (Exception e) {
            throw new IllegalArgumentException(e);
        }
    }

该计划的输出是;

diff[1] = 1072
diff[2] = 1080
diff[3] = 1080
diff[4] = 1080
diff[5] = 1080
diff[6] = 1088
diff[7] = 1088
diff[8] = 28584
diff[9] = 1088
diff[10] = 1096

为什么第8次运行会显示更高的分配? 我该怎么做才能使它更加一致?

2 个答案:

答案 0 :(得分:1)

来自文档

  

long getThreadAllocatedBytes(long id)

     

返回内存总量的近似值,以字节为单位,   在堆内存中为指定ID的线程分配。

答案 1 :(得分:0)

这很可能是由于使用了TLAB。为了提高性能,分配在线程本地分配缓冲区中完成。这允许分配非常快,只需将线程本地指针作为保留内存的一部分,直到TLAB满为止。

为了保持良好的性能,当对象适合TLAB时,不会进行分配跟踪,而是作为TLAB退出的一部分,内存会增加。

if (retire) {
  myThread()->incr_allocated_bytes(used_bytes());
}

所以很有可能你在使用TLAB作为8次迭代的一部分,因此看到了一个很大的突破。