堆空间在JVM中的位置属于中层。
-
一个JVM实例只存在一个堆内存,堆也是Java的核心区域。
-
Java对在JVM启动的时候即被创建,其空间大小也就确定了(类似数组)。是JVM管理的最大一块内存空间。
-
堆可以处于物理上不连续的内存空间中,但是在逻辑上它应该被视为连续的。
-
所有的线程都共享Java堆,在这里还可以划分线程私有的缓冲区(Thread Allocation Buffer,TLAB)-每个线程的独有堆空间
-
所有的对象实例以及数组都应当在运行时分配在堆上【规范】(实际不一定)
-
数组和对象可能永远不会存在栈上,因为栈帧中保存引用,这个引用指向对象或数组在堆中的位置【规范】(实际不一定)
-
在方法结束后,堆中的对象不会马上被移除,仅仅在垃圾收集的时候才会被移除
-
堆,是GC(Garbage Collection,垃圾收集齐)执行垃圾回收的重点区域
一个Java程序运行起来后是一个进程,一个进程对应一个JVM实例,一个JVM实例中有一个运行时数据区,运行时数据区只有一个堆和一个方法区。一个进程可以有多个线程,一个进程中的多个线程共享同一个堆空间和共享一个方法区。每个线程各自拥有一套程序计数器、本地方法栈和虚拟机栈。
堆内存的大小是可以调节的。

堆并不是分配对象的唯一选择
堆内存细分
现代垃圾收集器大部分基于分代收集理论设计
- Java7及之前堆内存逻辑上分为三部分:新生代+老年代+永久带
Permanent Space - Java8及之后堆内存逻辑上分为三部分:新生代+老年代+元空间Meta Space
存储在JVM中的Java对象可以被划分为两类:
- 一类是生命周期较短的瞬时对象,这些对象的创建和消亡非常迅速
- 另一类对象的生命周期却非常长,在某些极端的情况下还能与JVM的生命周期保持一致(连接操作对象的生命周期比较长)
Java堆内存进一步细分的话,可以划分为新生代(YongGen)和老年代(OldGen)
其中年轻代又可分为Eden空间(伊甸园)、Suvivor0空间(幸存者0区)和Suvivor1空间(幸存者1区)(有时也叫做from区、to区)
Java对象最先创建的位置是伊甸园,伊甸园死掉的对象直接回收,有的对象存活了就放在幸存者0区或1区,如果一定的时间(15GC cycles)对象还存活就放在老年代。

新生代与老年代的默认占比
新生代:老年代
1:2 新生代占整个堆1/3
Eden:幸存区1:幸存区2
8:1:1(实际上不一定 6:1:1)

- 几乎所有的Java对象都是在Eden区被new出来的
- 绝大部分的Java对象的销毁都在新生代进行了
- 可以使用``-Xmn`设置新生代的内存大小
测试阶段
jvisualvm.exe在JDK安装目录下,如C:\Program Files\Java\jdk1.8.0_122\bin



查看你自己安装的JDK版本,复制对应的链接
jdk1.7.0_79、jdk1.7.0_80、jdk1.8.0_40~jdk1.8.0_121:
请复制:https://visualvm.github.io/archive/uc/7u60/updates.xml.gz
jdk1.8.0_131~jdk1.8.0_271:
请复制:https://visualvm.github.io/uc/8u131/updates.xml.gz
https://visualvm.github.io/archive/uc/7u60/updates.xml.gz



package heap;
public class HeapDemo {
public static void main(String[] args) {
System.out.println("开始。。。");
try {
Thread.sleep(1000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("结束。。。");
}
}
-Xms10m -Xmx10m
分配不同的堆空间,初始堆空间和最大堆空间


2.5m+0.5m+7m=10m
网友评论