当前位置: 首页 > 科技观察

一篇理解JVM堆(Heap)的文章,你学会了吗?

时间:2023-03-12 11:19:54 科技观察

1。JVM堆的概念JVM中的堆是用来存放对象的内存空间。几乎所有的Java对象和数组都存储在JVM的堆内存中。比如我们创建一个新的对象或者创建一个数组的时候,都会在堆内存中分配一块空间用于存储。类加载器读取完class文件后,需要将类、方法、常量变量放入堆内存中,以保存所有引用类型的真实信息,以便后续执行。2.JVM堆的特点堆内存的存储特点:先进先出,后进后出。堆是JVM占用最大的区域,内存大小是运行时动态分配的。线程共享,整个Java虚拟机运行过程中只有一个堆,所有线程都访问同一个堆。JVM中的程序计数器、Java虚拟机栈、本地方法栈都对应一个线程。堆是在虚拟机启动时创建的。堆是JVM中涉及垃圾收集的主要地方。堆可以分为新生代(Eden区:FromSurvior,ToSurvivor)和老年代。JVM规范声明堆可以位于物理上不连续的内存空间中,但从逻辑上讲它应该被认为是连续的。关于Survivor(生存区)s0、s1区:复制后有交换,谁空谁给。3.JVM堆的内部结构3.1组成堆内存在逻辑上由新生代(Young)、老年代(Old)和永久代(Perm)组成。新生代(Young)包括:Eden、FromSurvivor(来自SurvivorArea)和ToSurvivor(ToSurvivorArea)。JDK1.7堆的内部构成:JDK1.8堆的内部构成,其中永久代(Perm)被元空间代替。堆内存的逻辑视角:堆=新生代+老年代+永久代或元空间;堆内存的物理角度:由年轻代(Young)和老年代(Old)组成,公式如下:堆内存实际大小=新生代的大小+老年代的大小。3.2堆内存内部空间比例新生代与老年代默认比例:1:2。新生代区域默认比例为:8:1:1。注意:在HotSpot中,Eden空间与另外两个SurvIvor空间的默认比例是8:1:1。3.3永久代和元空间的区别永久代:使用JVM内存;存储字符串和数组容易有性能和内存溢出问题,大小不易指定,GC复杂度高。Metaspace:不使用JVM的内存,而是使用计算机的本地内存。元空间的大小仅受本地内存的限制。元空间设置参数:-XX:MetaspaceSize(初始值)和-XX:MaxMetaspaceSize(最大值)。4、堆空间的大小设置-Xms:表示堆区的初始内存,相当于-XX:InitialHeapSize。-Xmx:表示堆区的最大内存,相当于-XX:MaxHeapSize。注意:如果堆中的内存大小超过“-Xmx”指定的最大内存值,则会抛出OutOfMemoryError异常。注意:一般情况下,-Xms和-Xmx这两个参数配置相同的值。目的是为了避免java垃圾回收机制清理完堆区后重新划分计算堆的大小,从而提高性能。默认情况下:初始内存:物理机内存大小/64。最大内存:物理机内存大小/4。5.堆空间垃圾收集堆空间垃圾收集有三种机制,MinorGC、MajorGC和FullGC。MinorGC:清理新生代内存空间(包括Eden和Survivor区),释放Eden中所有不活跃的对象。释放后,如果Eden空间不足以放置新的对象,JVM会尝试将Eden中的一些活动对象放入Survivor区。Survivor区作为Eden和老年代的中间交换区。如果老年代空间满了,Survivor区的对象会被移动到老年代,否则会一直保留在Survivor区。MajorGC:清理老年代的内存空间。当老年代空间不足时,JVM会在老年代进行MajorGC。FullGC:清理JVM整个堆内存空间,包括新生代和老年代空间。