JVM 内存布局以及垃圾收集及管理详解
最近在学习周志明的《深入理解JAVA虚拟机》,首先最实用而且也是我最想了解的就是java的内存布局,也学到了许多,借此给大家分享一下。 JAVA的内存布局主要分为 方法区,虚拟机栈(VM Stack),本地方法栈(Native Method Area),堆(heap),程序计数器(Program counter register)。其中方法区和堆是线程共享的,而栈和程序计数器是每个
最近在学习周志明的《深入理解JAVA虚拟机》,首先最实用而且也是我最想了解的就是java的内存布局,也学到了许多,借此给大家分享一下。
JAVA的内存布局主要分为 方法区<Method Area>,虚拟机栈(VM Stack),本地方法栈(Native Method Area),堆(heap),程序计数器(Program counter register)。其中方法区和堆是线程共享的,而栈和程序计数器是每个线程都会有自己的分配空间,即非共享(线程私有)。
存储内容
程序计数器主要是记录当前线程所执行的字节码的行号指示器。
虚拟机栈主要存放的则是存储局部变量表,操作数栈,动态链接,方法出口等信息
本地方法栈和虚拟机栈基本一样,只不过本地方法栈主要存储的是native的方法信息。
java堆是内存中最大的一块,主要存放的是对象实例和数组。
方法区是线程共享的内存区域,主要存储已被虚拟机加载的类信息,常量,静态变量,即时编译器所编译后的代码等数据。
垃圾收集
常用的垃圾收集方法是引用计数算法,但java虚拟机并不是,因为有可能有对象相互依赖,但都没有用的对象。在java虚拟机中常用的则是可达性分析算法。通过一系列的GC Root 作为起始点,所走出来的一系列引用链,没有在引用链之内的对象则会被回收。
垃圾收集算法
在java虚拟机中,主要有标记-清除(Mark-Sweep)算法,复制(Copying)算法,标记-整理(Mark-Compact)算法,分代收集(Generational Collection)算法。
标记-清除(Mark-Sweep)算法,缺点主要有容易产生大量的内存碎片。
复制(Copying)算法,主要是把内存分为一个较大的Eden空间和两个较小的Survior空间,在java虚拟机 中,默认比例是8:1:1,缺点,在某些情况下需要内存担保。
标记-整理(Mark-Compact)算法,是在标记-清除(Mark-Sweep)算法的基础上进行了对象向一边的移动,不会出现大量的内存碎片。
分代收集(Generational Collection)算法,在java中最常用的,主要分为新生代和老年代。不同的年代使用不同的算法。
算法实现
垃圾收集器
主要有Serial ,ParNew,Parallel Scavenge,Serial Old,Parallel Old,CMS(Concurrent Mark Sweep),G1收集器。
在垃圾收集过程中,需要所有的用户线程暂停,因此会产生一个停顿时间。
其中前3个收集器主要用于新生代中,中间3个主要用于老年代中,最后一个收集器是最新的收集器,独自管理新老年代。
Serial和Serial Old是单线程(垃圾收集线程),其余的都是多线程。
Parallel Scavenge是注重于吞吐量的收集器,执行代码的时间/执行代码时间+垃圾收集时间。
CMS(Concurrent Mark Sweep),G1则都是以减少停顿时间为目标的。
在当前jdk中,主要分为server模式和client模式,默认是client模式,而在不同的模式中默认的垃圾收集算法也是不一样的。在client模式中,新生代和老年代默认是Serial和Serial Old,在server模式中默认的新生代和老年代收集器是ParNew和Serial Old。
Java虚拟机常用的垃圾收集器相关参数如下:
参数 | 描述 |
UseSerialGC | 虚拟机运行在Client模式的默认值,打开此开关参数后, |
UseParNewGC | 打开此开关参数后,使用ParNew+Serial Old收集器组合进 |
UseConcMarkSweepGC | 打开此开关参数后,使用ParNew+CMS+Serial Old收集器组 |
UseParallelGC | 虚拟机运行在Server模式的默认值,打开此开关参数后, |
UseParallelOldGC | 打开此开关参数后, |
SurvivorRation | 新生代内存中Eden区域与Survivor区域容量比值,默认是8,即 |
PretenureSizeThreshold | 直接晋升到年老代的对象大小,设置此参数后,超过该大小的 |
MaxTenuringThreshold | 直接晋升到年老代的对象年龄,每个对象在一次Minor GC之后还 |
UseAdaptiveSizePolicy | java虚拟机动态自适应策略,动态调整年老代对象年龄和各个区域大小。 |
HandlePromotionFailure | 是否允许担保分配内存失败,即整个年老代空间不足,而整个新生代中Eden和Survivor对象都存活的极端情况。 |
ParallelGCThreads | 设置并行GC时进行内存回收的线程数。 |
GCTimeRation | Parallel Scavenge收集器运行时间占总时间比率。 |
MaxGCPauseMillis | Parallel Scavenge收集器最大GC停顿时间。 |
CMSInitiatingOccupancyFraction | 设置CMS收集器在年老代空间被使用多少百分比之后触发垃圾收集,默认是68%。 |
UseCMSCompactAtFullCollection | 设置CMS收集器在完成垃圾收集之后是否进行一次内存整理。 |
CMSFullGCsBeforeCompaction | 设置CMS收集器在进行多少次垃圾收集之后才进行一次内存整理。 |
-verbose:gc可以查看Java虚拟机垃圾收集结果。
更多推荐
所有评论(0)