①. 堆的概述(共享|垃圾回收)
①. 一个JVM实例只存在一个堆内存,堆也是Java内存管理的核心区域
②. 堆可以在物理上不连续的内存空间中,但在逻辑上是连续的
③. Java堆区在JVM启动的时候即被创建,其空间大小也是确定的。是Jvm管理最大的一块内存空间
④. 所有的线程共享Java堆,在这里还可以划分线程私有的缓冲区(Thread Local Allocation Buffer,TLAB)
⑤. 在方法结束后,堆中的对象不会马上被移除,仅仅在垃圾收集的时候才有被移除
(注意:一个进程就是一个JVM实例,一个进程中包含多个线程)
⑥. 举例
public class SimpleHeap { private int id; public SimpleHeap(int id) { this.id = id; } public void show() { System.out.println("My ID is " + id); } public static void main(String[] args) { SimpleHeap sl = new SimpleHeap(1); SimpleHeap s2 = new SimpleHeap(2); } }
②. 堆的内存结构
- ①. 现在垃圾收集器大部分都基于分带收集理论设计的,堆空间细分为:
②. jdk1.7 堆中的结构
③. jdk 1.8 堆中的结构
③. 堆空间大小的设置 -Xms -Xmx
①. Java堆区用于存储Java对象实例,那么堆的大小在JVM启动时就已经设定好了,大家可以通过选项"-Xmx 和 -Xms"来设置
②. -Xms(物理内存的1/64):表示堆区的起始内存,等价于-XX:InitialHeapSize
③. -Xmx(物理内存的1/4):则用于表示堆区的最大内存,等价于-XX:MaxHeapSize
④. 通常会将-Xms和-Xmx两个参数配置相同的值,其目的是为了能够在java垃圾回收机制清理完堆区后不需要重新分隔计算堆区的大小,从而提升性能
⑤. 案列演示
package com.xiaozhi.heap; import java.util.concurrent.TimeUnit; /** * -Xms:600m * -Xmx:600m * 查看设置的参数: * 方式一(cmd中):jps / jstat -gc 进程id * 方式二(XX:+PrintGCDetails) */ public class HeapDemo1 { public static void main(String[] args)throws Exception { //返回Java虚拟机中的堆内存总量 long initialMemory = Runtime.getRuntime().totalMemory()/1024/1024; //返回Java虚拟机试图使用的最大堆内存量 long maxMemory = Runtime.getRuntime().maxMemory()/1024/1024; System.out.println("-Xms:"+initialMemory+"M"); System.out.println("-Xmx:"+maxMemory+"M"); //TimeUnit.SECONDS.sleep(1000000); } }
④. 新生代与老年代参数设置 NewRation SurvivorRatio
①. 配置新生代与老年代在堆结构占比
默认:-XX:NewRatio=2,表示新生代占1,老年代占2,新生代占整个堆的1/3
可以修改-XX:NewRatio=4,表示新生代占1,老年代占4,新生代占整个堆的1/5
②. -XX:SurvivorRatio调整这个空间比例(Eden空间和另外两个Survivor空间缺省所占的比例是8:1:1)
③. -Xmn:设置新生代最大内存大小,一般使用默认值就可以了
④. 几乎所有的Java对象都是在Eden区被new出来的,觉大部分的Java对象的销毁都在新生代进行的