03.堆
堆
在 Java 虚拟机中,堆是可供各个线程共享的运行时内存区域,也是供所有类实例和数组对象分配内存的区域。这块区域随着虚拟机的启动而创建,它的唯一使命就是存放对象实例,这块区域也是 GC 主要关注的地方。
堆内存是内存中最重要的一块,也是最有必要进行深究的一部分。因为 Java 性能的优化,主要就是针对这部分内存的。所有的对象实例及数组都是在堆上面分配的(随着 JIT 技术的逐渐成熟,这句话视乎有些绝对,不过至少目前还基本是这样的),可通过-Xmx 和-Xms 来控制堆的大小。JIT 技术的发展产生了新的技术,如栈上分配和标量替换,也许在不久的几年里,即时编译会诞生及成熟,那个时候,“所有的对象实例及数组都是在堆上面分配的”这句话就应该稍微改改了。堆内存是垃圾回收的主要区域,所以在下文垃圾回收板块会重点介绍,此处只做概念方面的解释。在 32 位系统上最大为 2G,64 位系统上无限制。可通过-Xms 和-Xmx 控制,-Xms 为 JVM 启动时申请的最小 Heap 内存,-Xmx 为 JVM 可申请的最大 Heap 内存。
Heap Usage:
PS Young Generation
Eden Space:
capacity = 17301504 (16.5MB)
used = 2483088 (2.3680572509765625MB)
free = 14818416 (14.131942749023438MB)
14.351862127130682% used
From Space:
capacity = 2621440 (2.5MB)
used = 2615312 (2.4941558837890625MB)
free = 6128 (0.0058441162109375MB)
99.7662353515625% used
To Space:
capacity = 6291456 (6.0MB)
used = 0 (0.0MB)
free = 6291456 (6.0MB)
0.0% used
PS Old Generation
capacity = 44564480 (42.5MB)
used = 13316368 (12.699478149414062MB)
free = 31248112 (29.800521850585938MB)
29.88112505744485% used
PS Perm Generation
capacity = 22020096 (21.0MB)
used = 14907008 (14.2164306640625MB)
free = 7113088 (6.7835693359375MB)
67.6972888764881% used
新生代
JVM 每次只会使用 Eden 和其中的一块 Survivor 区域来为对象服务,所以无论什么时候,总是有一块 Survivor 区域是空闲着的。因此,新生代实际可用的内存空间为 9/10 ( 即 90% )的新生代空间。 假如某个 Java 进程的 JVM 参数配置如下:-Xms1G -Xmx2G -Xmn500M -XX:MaxPermSize=64M -XX:+UseConcMarkSweepGC -XX:SurvivorRatio=3,其中-Xmn500M 表示年轻代大小是 500M,-XX:SurvivorRatio=3 表示 Eden 区与两个 Survivor 区的大小比值为 3:1:1,故 Eden 区的大小为 300M。