【发布时间】:2017-06-02 16:12:51
【问题描述】:
我在玩jmap,发现简单的“Hello World”Java 程序创建了数千个对象。这是 Oracle JVM 更新 131 在启动时创建的对象的截断列表:
num #instances #bytes class name
----------------------------------------------
1: 402 4903520 [I
2: 1621 158344 [C
3: 455 52056 java.lang.Class
4: 194 49728 [B
5: 1263 30312 java.lang.String
6: 515 26088 [Ljava.lang.Object;
7: 115 8280 java.lang.reflect.Field
8: 258 4128 java.lang.Integer
9: 94 3760 java.lang.ref.SoftReference
10: 116 3712 java.util.Hashtable$Entry
11: 126 3024 java.lang.StringBuilder
12: 8 3008 java.lang.Thread
13: 74 2576 [Ljava.lang.String;
14: 61 1952 java.io.File
15: 38 1824 sun.util.locale.LocaleObjectCache$CacheEntry
16: 12 1760 [Ljava.util.Hashtable$Entry;
17: 53 1696 java.util.concurrent.ConcurrentHashMap$Node
18: 23 1472 java.net.URL
19: 14 1120 [S
20: 2 1064 [Ljava.lang.invoke.MethodHandle;
21: 1 1040 [Ljava.lang.Integer;
22: 26 1040 java.io.ObjectStreamField
23: 12 1024 [Ljava.util.HashMap$Node;
24: 30 960 java.util.HashMap$Node
25: 20 800 sun.util.locale.BaseLocale$Key
我知道 JVM 从 JAR 文件中加载类并期望看到 java.lang.Class、java.lang.String 和 [Ljava.lang.Object。 258 个java.lang.Integer 对象也很清楚,这就是Integer 缓存。
但是java.lang.reflect.Field? Hashtable?很多StringBuilders? java.util.concurrent.ConcurrentHashMap?这是哪里来的?
程序很简单:
public class Test {
public static void main(String[] args) throws IOException {
System.out.println("Hello world");
System.in.read();
}
}
JVM 详细信息:
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
Ubuntu 16.04。
【问题讨论】:
-
一个 java.lang.Class 有 java.lang.Fields,那为什么没有 Field 实例呢? Hashtable 在内部被大量使用,在你不直观地期望它的地方。由于程序如此简单,垃圾收集器可能甚至没有运行一次,所以您会看到在 VM 启动期间创建的每个单个对象。