jmap输出中[C与String的区别

clipboard.png
如图,jmap打出的heap中,同时出现了[C和String。
有点奇怪的是,String本身是用final char[]来保存的,这里同时列出来,意味着[C的实例数和内存占用是包括String的,还是说String是单独统计的?

阅读 6.9k
1 个回答

String实际占用的内存应是上图的String+[C的才对.

为验证这个我写了个小程序

import java.io.*;
import java.util.*;

public class MemoryMap {
    static long bytes = 0;

    public static void main(String[] args) throws IOException { // Line 1
        Set<String> opt = new HashSet<String>();
        opt.addAll(Arrays.asList(args));
        List<String> list= new ArrayList< String>();
        if (opt.contains("alloc")) {
            for (int i = 0; i < 100; i++) {
                String s = foo(1024 * 1024, i); //100Mb
                bytes += s.getBytes().length;
                list.add(s);
            }
        }
        System.out.println("Bytes=" + bytes + ", press Enter to exit...");

        InputStreamReader in = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader(in);
        if(opt.contains("gc")){
            System.gc();
        }
        String a = br.readLine();
        System.out.println(a);
        System.out.println(list.size());
    }

    private static String foo(long count, int k) { // Line 6
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < count; i++) {
            sb.append(i % 10);
        }
        sb.append(k);
        return sb.toString();
    } 

}

编译

javac MemoryMap.java

分别运行

java MemoryMap alloc gc 
和
java MemoryMap gc 

并另打开一个终端窗口分别查看

分配100M+字符的情况

?  $ jps
12426 MemoryMap
12428 Jps

?  $ jmap -histo 12426

 num     #instances         #bytes  class name
----------------------------------------------
   1:          1160      209829280  [C
   2:            92        9702688  [I
   3:           485          55304  java.lang.Class
   4:            11          33232  [B
   5:          1147          27528  java.lang.String
   6:           525          26424  [Ljava.lang.Object;
   7:            79           5688  java.lang.reflect.Field

不分配的情况

?  $ jmap -histo 12912

 num     #instances         #bytes  class name
----------------------------------------------
   1:            92         685024  [I
   2:          1038         110832  [C
   3:           485          55304  java.lang.Class
   4:            14          33872  [B
   5:           524          25968  [Ljava.lang.Object;
   6:          1025          24600  java.lang.String
   7:            79           5688  java.lang.reflect.Field

两种情况字符串字节数相差27528-24600=2928
字符数组字节数相差209829280-110832=209718448

实际上100M+数字字符在内存占200M+字节

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题