最近在学习周志明的《深入理解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模式的默认值,打开此开关参数后,
使用Serial+Serial Old收集器组合进行垃圾收集。

UseParNewGC

打开此开关参数后,使用ParNew+Serial Old收集器组合进
行垃圾收集。

UseConcMarkSweepGC

打开此开关参数后,使用ParNew+CMS+Serial Old收集器组
合进行垃圾收集。Serial Old作为CMS收集器出现Concurrent
Mode Failure的备用垃圾收集器。

UseParallelGC

虚拟机运行在Server模式的默认值,打开此开关参数后,
使用Parallel Scavenge+Serial Old收集器组合进行垃圾收集。

UseParallelOldGC

打开此开关参数后,
使用Parallel Scavenge+Parallel Old收集器组合进行垃圾收集。

SurvivorRation

新生代内存中Eden区域与Survivor区域容量比值,默认是8,即
Eden:Survivor=8:1.

PretenureSizeThreshold

直接晋升到年老代的对象大小,设置此参数后,超过该大小的
对象直接在年老代中分配内存。

MaxTenuringThreshold

直接晋升到年老代的对象年龄,每个对象在一次Minor GC之后还
存活,则年龄加1,当年龄超过该值时进入年老代。

UseAdaptiveSizePolicy

java虚拟机动态自适应策略,动态调整年老代对象年龄和各个区域大小。

HandlePromotionFailure

是否允许担保分配内存失败,即整个年老代空间不足,而整个新生代中Eden和Survivor对象都存活的极端情况。

ParallelGCThreads

设置并行GC时进行内存回收的线程数。

GCTimeRation

Parallel Scavenge收集器运行时间占总时间比率。

MaxGCPauseMillis

Parallel Scavenge收集器最大GC停顿时间。

CMSInitiatingOccupancyFraction

设置CMS收集器在年老代空间被使用多少百分比之后触发垃圾收集,默认是68%。

UseCMSCompactAtFullCollection

设置CMS收集器在完成垃圾收集之后是否进行一次内存整理。

CMSFullGCsBeforeCompaction

设置CMS收集器在进行多少次垃圾收集之后才进行一次内存整理。

java虚拟机的-XX:+PrintGCDetails参数可以打印垃圾收集器的日志信息。

-verbose:gc可以查看Java虚拟机垃圾收集结果。

 

 

 

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐