Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java阵列使用多少内存?_Java_Arrays_Profiling - Fatal编程技术网

Java阵列使用多少内存?

Java阵列使用多少内存?,java,arrays,profiling,Java,Arrays,Profiling,我试图找出一个数组在JVM中使用了多少内存。我为此制定了一个计划,这给了我奇怪的结果 protected static long openMem(){ System.gc(); System.runFinalization(); return Runtime.getRuntime().freeMemory(); } public static double listSize(int limit){ long start= openMem(); Objec

我试图找出一个数组在JVM中使用了多少内存。我为此制定了一个计划,这给了我奇怪的结果

protected static long openMem(){
    System.gc();
    System.runFinalization();
    return Runtime.getRuntime().freeMemory();
}

public static double listSize(int limit){
    long start= openMem();
    Object[] o= new Object[limit];
    for(int i= 0; i<limit; i++ ){
        o[i]= null;
    }
    long end= openMem();
    o= null;
    return (start-end);
}

public static void list(int i){
    for(int y= 0; y<50; y++ ){
        double d= Quantify.listSize(i);
        System.out.println(i+" = "+d+" bytes");
    }
}

public static void main(String ... args){
        list(1);
        list(2);
        list(3);
        list(100);
    }
当我运行此命令时,对于每个大小的数组,我会得到两个不同的字节大小,如:

1=24.0字节 1=208.0字节 1=24.0字节 1=208.0字节 1=208.0字节 1=208.0字节 1=208.0字节 1=24.0字节 因此,1个元素的数组只返回24个字节或208个字节,其他所有元素的模式相同:

1=24.0字节

1=208.0字节

2=24.0字节

2=208.0字节

3=32.0字节

3=216.0字节

100=416.0字节

100=600.0字节


我在想为什么会这样。我想知道的是,这里的其他人是a已经知道答案,还是b知道如何找到答案。

在JVM上测量堆占用率甚至比测量性能更棘手。首先,有线程本地分配缓冲区TLAB,它们是一次分配的堆块,与分配的对象大小无关。您应该禁用它们用于测量:-XX:-UseTLAB。此外,您的代码在某些方面是正确的,但在其他方面几乎是正确的。例如,我建议运行两个GC;无需运行终结;并在分配前运行GC,然后在解除分配后运行GC。仅在每次测量之前运行它。您还需要使用totalMemory freeMemory,否则易受堆大小调整的影响

总之,试着用这个代码测量,它会给我可靠的结果

class Quantify {
  static final Object[][] arrays = new Object[20][];

  static long takenMem(){
    final Runtime rt = Runtime.getRuntime();
    return rt.totalMemory() - rt.freeMemory();
  }

  static long arraySize(int size){
    System.gc(); System.gc();
    long start = takenMem();
    for (int i = 0; i < arrays.length; i++) arrays[i] = new Object[size];
    final long end = takenMem();
    for (int i = 0; i < arrays.length; i++) arrays[i] = null;
    System.gc(); System.gc();
    return (end - start) / arrays.length;
  }
  public static void main(String... args) {
    for (int i = 1; i <= 20; i++) System.out.println(i+": "+arraySize(i));
  }
}

这与实际情况一致:由于报头的开销,最小分配为24字节;由于内存对齐问题,大小会更改8这是64位JVM的典型情况。

我从不建议通过freemem增量测量任何内容。创建一些类型化数组,例如MyClass[],然后运行jmap-histo:live。内存无论如何都不是确定性的,Java运行时可能有自己的缓存和对象、线程,因此您可以通过freemem的增量来量化任何内容,您可能会得到当前已使用或可用内存的大致数字,但尝试测量像数组这样的单个对象是徒劳的。数组使用对象标头+4bytes length+sun.misc.Unsafe.ADDRESS_SIZE*array.length更简单的度量方法是jmap-Histori使用VisualVM的这些度量值时,它可能在内部依赖于jmap或类似的度量:它没有考虑压缩的OOP。这向我表明,它的报告并非来自直接测量,而是来自一些硬编码的大小数据,这些数据可能与实际情况不同步。jmap和jstack使用调试接口连接到jvm,visualvm可能使用相同的接口。visualvm不太喜欢visualvm,因为它不能真正用于生产。但是,所有快照都是在主机进程中执行的,因此如果不考虑压缩,则可能是某个错误。总的来说,我强烈建议您掌握jmap,因为它是分析生产服务器内存分配/使用和泄漏的不可或缺的工具。顺便说一句,有两种不同的模式-一种是直方图模式,另一种是内存转储模式。直方图是在主机进程中执行的,内存转储正确地使用任何估计大小。@bestsss是的,我们也使用jmap进行生产分析。我们也设法使用了VisualVM,但是为所有端口设置SSH隧道是一件非常痛苦的事情,这些端口没有确切的文档记录,有些甚至在运行之间进行了更改。但从VisualGC的角度来看生产服务器是一种全新的体验:
1: 24
2: 24
3: 32
4: 32
5: 40
6: 40
7: 48
8: 48
9: 56
10: 56
11: 64
12: 64
13: 72
14: 72
15: 80
16: 80
17: 88
18: 88
19: 96
20: 96