• JVM


    JVM:

    首先了解一下并行和串行的区别:

    并行:未包含用户线程,是有多个GC线程

    并发:包含了用户线程,GC与用户线程一起(交替)工作

    HotSpot和Client:

    HotSpot:最主要的一个特点就是它可以把经常使用的CLASS文件保存在缓存里,这样就提高了JVM的效率。

    Client:和HotSpot是两种不同的机制,并不是说是用了两套虚拟机,而是一套虚拟机下不同的两种初始化方法。Client更多的基于桌面级应用而进行内存分配。

    关于JVM的一些知识:

    (1)类加载子系统与方法区:类加载子系统负责从文件系统或者网络中加载CLASS信息,加载的类信息存放在一块称为方法区的内存空间。除了类的信息外,方法区中还可能会存放运行时的常量池信息,包括字符串字面量和数字常量(这部分信息是CLASS文件中常量池的内存映射)

    (2)Java堆:Java堆在虚拟机启动的时候建立,它是Java程序最主要的内存工作区域,几乎所有的Java对象实例都存放在堆区中,堆空间是所有线程共享的,这是一块与Java应用密切相关的内存空间

    (3)直接内存:Java的NIO库允许Java使用直接内存,直接内存是在Java堆外的、直接向系统申请的内存空间。通常访问直接内存的速度要快于访问Java堆,因此出于提高性能的考虑,读写频繁的场合可能会考虑使用直接内存,由于直接内存在Java堆外,因此它的大小不会受限于XMX指定的最大堆大小,但是系统内存是有限的,Java堆和直接内存的总和依然受限于操作系统能给出的最大内存。

    (4)垃圾回收系统:垃圾回收系统是Java虚拟机的重要组成部分,垃圾回收器可以对方法区、Java堆和直接内存进行回收。其中Java堆是垃圾回收器的工作重点。和C/C++不同,Java中所有对象的空间释放都是隐式的,也就是说Java中没有类似于FREE()、DELETE()这样的方法释放指定的内存区域。

    (5)Java栈:每一个Java虚拟机线程都有一个私有的Java栈,一个线程Java栈在一个Java线程创建的时候被创建,其中保存着帧信息,Java栈中保存着局部变量,方法参数,同时和方法的调用返回密切相关。栈帧:当新方法进入栈时,没有运行完的方法就会保存起来,形成栈帧

    (6)本地方法栈:和Java栈非常类似,最大的不同就是Java栈用于Java方法的调用,本地方法栈用于本地方法的调用(nativemethod),一般Java程序的运行都离不开操作系统的方法。这也是为什么不同JVM的API不同,因为不同操作系统里有着不同的本地方法。Java虚拟机允许Java直接调用本地方法,一般都是使用C语言编写的。

    (7)PC寄存器:PC寄存器也是每一个Java线程私有的空间,Java虚拟机会为每一个线程创建一个PC寄存器,在任意时刻,一个Java线程总是在执行一个方法,这个被执行的方法被称为当前方法,如果正在执行的方法不是本地方法那么PC就会指向当前正在被执行的指令,如果当前方法是本地方法那么PC寄存器的值就是UNDEFINED

    (8)执行引擎:执行引擎是Java虚拟机最核心的组件之一,它负责执行字节码,现在的虚拟机为了提高效率,使用即时编译(JUST IN TIME)技术将字节码译成机器码再执行。

    JVM堆结构及分代:

    Java虚拟机根据对象存活的周期不同,一般将堆内存划分为新生代、老年代、永久代(对于HOTSPOT而言)

    分代:堆内存是虚拟机管理的内存中最大的一块,也是垃圾回收最频繁的一块区域,程序的所有对象都放在堆内存中,给堆内存分代是为了提高内存的利用率和垃圾回收的效率。如果不分代各种生命周期的对象杂糅,每次想要找出指定对象的时候都要全部遍历,效率大大降低,分代之后还提高了内存的利用率,而且还可以根据不同代的对象采用更为适合的垃圾回收算法,提高效率,即分代垃圾回收。

    新生代:朝生夕死,常规应用进行一次垃圾收集可以回收70%-95%的空间,回收效率很高。HOTSPOT将新生代分为三个部分,一块较大的EDEN区,两块较小的SURVIVOR,默认比例8:1:1,划分的目的是因为HOTSPOT采用复制算法来回收新生代,设置这个比例是为了充分利用内存空间减少浪费,大对象一般直接存在老年代中。新生代中的对象没经过一次垃圾回收年龄加一。

    复制算法:当在EDEN区没有足够的空间分配内存时,会调用GC,当调用GC的时候,对象都存在EDEN区和FROM SURVIVOR区中,TO SURVIVOR区中为空,是一块儿保留空间。GC时达到年龄阈值的对象会被复制到老年代中,没有达到阈值的就会被存到TO SURVIVOR中,接着清空EDEN和FROM SURVIVOR,在GC结束后又将TO SURVIVOR 中的对象复制到FROM SURVIVOR中。总之不管怎么样在一轮GC后TO SURVIVOR区都保证是空的。GC时当TO SURVIVOR没有足够的空间存放上一次新生代收集下来的存活对象时,需要依赖老年代进行分配担保,将这些对象放在老年代中。

    老年代:在新生代中经历了多次GC后(次数看虚拟机的配置)仍然存活下来的对象,老年代中GC频率较低,回收速度较慢

    永久代:永久存储类信息、常量、静态变量、即时编译器编译后的代码等数据,对这一区域而言,JVM不会对其进行GC。

    JVM垃圾回收常见的算法:

    1、引用计数:当这个对象有引用的时候就给计数器+1,删除引用就-1,致命的缺点就是无法处理循环引用。

    2、复制算法:把内存划成两个区域,每次只使用一个区,GC时只处理正在使用的区。复制后还会进行有序的整理,缺点是需要两倍的内存空间

    3、标记-清除:分为两个阶段,第一阶段遍历内存,标记被引用的对象,第二阶段遍历内存,回收未标记的对象。GC时会暂停整个应用,并且会产生碎片,也就是会浪费内存。

    4、标记-整理:结合了赋值和清除两个算法的优点,也是两个阶段,第一阶段标记被引用的对象,第二阶段时回收未标记的并且按顺序压缩标记的

    垃圾收集器与垃圾收集算法

    次收集(SCAVENGE GC):当年轻代堆空间紧张时就会触发,触发频繁

    全收集(FULL GC):当老年代或持久代堆空间满了会触发全收集操作

    SYSTEM.GC()是让FULL GC优先启动

    HOTSPOT的七个收集器:

    新生代(YOUNG GENERATION)中:SERIAL、PARNEW、PARALLEL SCAVENGE

    老年代(TENURED GENERATION):CMS(COUCURRENT MARK SWEEP)、SERIAL OLD、PARALLEL OLD

    新老代:G1(GARBAGE FIRST)

    SERIAL(串行收集器):特点是只用一条线程进行GC,且需要暂停其他所有的工作线程,所以也称STOP THE WORLD(STW),回收新生代时使用的是复制算法,回收老年代使用的是标记-整理算法

    PARNEW(并行收集器):是SERIAL的多线程版本,除了用多个线程进行GC外其他的都与SERIAL一样,是启动CMS后的默认新生代收集器

    PARALLEL SCAVENGE:跟PARNEW一样,使用复制算法,也是多线程,PARALLEL SCAVENGE更关注系统吞吐量(运行用户代码时间/(运行用户代码时间+垃圾回收时间))

    SERIAL OLD:在老年代里使用的是标记-整理算法,不能再使用复制算法,因为没有空间进行复制。SERIAL OLD兼容性很好,可以和年轻代所有收集器协作使用

    PARALLEL OLD:使用多线程和“标记-整理”算法,吞吐量优先,他只能和PARALLEL SCAVENGE配合使用

    CMS:特点:GC与用户线程一起(交替)工作

     

    监视JVM的工具:jvisualvm 插件gc

    JVM参数介绍:

    -Xms:初始堆大小

    -Xmx:允许申请的最大堆的大小

    -XX:NewSize=n:设置年轻代大小

    -XX:NewRatio=n:按照多大的比例

    -XX:SurvivorRatio=n:Eden区与两个Survivor区的比值

    -XX:MaxPermSize=n:设置持久代大小

    收集器:

    -XX:+UseSerialGC,虚拟机运行在Client模式下的默认值,Serial+Serial Old。

    -XX:+UseParNewGC,ParNew+Serial Old,在JDK1.8被废弃,在JDK1.7还可以使用。

    -XX:+UseConcMarkSweepGC,ParNew+CMS+Serial Old

    -XX:+UseParallelGC,虚拟机运行在Server模式下的默认值,Parallel Scavenge+Serial Old(PS Mark Sweep)。

    -XX:+UseParallelOldGC,Parallel Scavenge+Parallel Old。

    -XX:+UseG1GC,G1+G1。

  • 相关阅读:
    第87天:HTML5中新选择器querySelector的使用
    第86天:HTML5应用程序标签和智能表单
    第85天:HTML5语义化标签
    第84天:jQuery动态创建表格
    第83天:jQuery中操作form表单
    第82天:jQuery中prop()和attr()的区别
    第81天:jQuery 插件使用方法
    第80天:jQuery插件使用
    第79天:jQuery事件总结(二)
    对事务的特性ACID的理解
  • 原文地址:https://www.cnblogs.com/tutuhome/p/10699801.html
Copyright © 2020-2023  润新知