JVM的学习笔记

JVM知识点

下载 JVM知识点.md (11.4 KB)

Java源代码 -> 编译成.class字节码 ->由JVM解释字节码 -> 底层执行机器码

JVM内存模型

线程私有:{
    虚拟机栈:每个方法在执行的同时都会创建一个 栈帧{局部变量表、操作数栈、动态链接、方法出口}
    本地方法栈:native方法,非java实现的底层代码,如c/c++
    程序计数器(PC寄存器):是当前线程所执行字节码的行号指示器,控制程序执行顺序、循环等
}

线程共享:{
    堆:{
       创建的对象和数组都保存在这,也是垃圾收集器主要回收的区域。
       目前采用分代收集算法,从GC的角度分析还可细分为:(新生代、老年代,占堆的比例1:3)
       新生代:{
            (Eden区、From Survivor,To Survivor区)存储比例8:1:1,小数据,生存周期短
             Eden区:Java新对象的出生地,当此区域内存不足时会触发MinorGC,对新生代进行垃圾回收
             From区:上一次GC 的幸存者,作为这一次的GC的被扫描者
             To区  : 保留了一次 MinorGC 过程中的幸存者。
             MinorGC采用复制算法:
             1.将Eden和From区域中存活的对象复制到To区域,同时把这些对象的年龄+1,如果年龄达到了(15)
               老年代的标准,则放入老年代。
             2.清空eden和From区
             3.to和from互换,to成为下次GC的from区

       }
       老年代:{
            较大的数据对象,生命周期长,老年代对象比较稳定,采用MajorGC且不会频繁执行
            采用标记清除算法:首先扫描一次所有老年代,标记处存活的对象,然后回收没有标记的对象
            如果老年待业装满了装不下的时候,会抛出OOM异常
       }  
    }

    方法区:{
       用于存储JVM加载的类信息、常量、静态变量、即时编译后的代码等数据
       运行时的常量池是方法区的一部分,用于存储编译期间生成的各种字面量和符号引用,类加载后放入。
       永久代:指内存永久保存的区域,主要存放Class和Meta元数据,GC不会在程序运行期间对永久代进行清理,
       所以当加载的class越来越多时,可能抛出OOM,在Java8中,永久代已被出,被“元数据区”所代替,元空间不       在虚拟机中,而是使用本地内存,因此,默认情况下元空间的大小受本地内存限制,类的元数据放入本地存储,
       字符串和类的静态变量方法堆中,有效减少OOM情况。
    }

}

垃圾回收算法

如何确定一个垃圾?{(重点)
    1.引用计数法:Java中引用和对象都有关联的,如果要操作对象则必须用引用进行,所以可用个计数器判断一个
      对象是否可用回收,如果计数为0,则回收,有循环引用,造成无法回收的弊端。
    2.可达性分析:为了解决循环引用问题,通过“GC roots”对象作用起点搜索,如果在root 和一个对象之间没有
      可达的路径,则表示此对象可被回收,不过要经历两次标记过程才能回收。
}

标记清除算法(Mark-Sweep):{
    最基础的垃圾回收算法,分为两阶段,标记和清除,标记处所有需要回收的对象,再进行清除;
    缺点:效率偏低、内存碎片化严重,后续可能发生大对象不能找到可利用空间的问题
    适用场景:适合在老年代进行垃圾回收,比如CMS收集器就是采用该算法进行回收的;
}

复制算法:{
    可解决内存碎片化严重的情况,将可用内存分为两块,每次只是用其中的一块,当这块内存用完了,将还存活的对象
    复制到另一块中去,将当前使用过的内存一次性清理掉,效率较高。
    缺点:可用内存被压缩到了原来的一半,且存活对象增多的话,效率会降低;
    适用场景:
        适合新生代区,新生代中只有少量对象存活只要付出少量复制成本即可收集完成,serial new,parallel 
        new和scanvage收 集器采用此算法。
}

标记整理算法(Mark-Compact):{
    分为标记和整理两阶段,综合以上两种算法,设计的更精妙的算法,标记阶段和Mark-sweep算法相同,但标记后不    清除,而是将存活的对象移动至内存的一端,然后清除端边界的对象。
    适用于老年代,GC 和serial old收集器采用此算法,因为对象的存活率高,不必进行内存复制,直接腾出空闲内存
}

分代收集:{
    根据不同的对象生存周期,将内存划分为几块,然后对其采用合适的收集算法。
    分为新生代和老年代,新生代特点是每次垃圾回收都需要回收大量的垃圾,老年代则只有少量的垃圾需要回收。
    新生代:采用复制算法
    老年代:采用标记整理算法
}

Java中四种引用类型

强引用:{
    把一个对象赋值给一个引用变量(Test str = new Test();),这就是强引用,它处于可达状态,它是不可能
    被回收的,即使永远不会被用到也不回收,这也内存泄漏的主要原因之一。
}

软引用:需要用SoftReference 类实现,当系统内存足够时它不会被回收,不足则回收。
弱引用:需要用WeakReference 类实现,它比软引用生存期更短,只要垃圾回收机制一运行,就会回收它。
虚引用:用PhantomReference类实现,不能单独使用,必须和引用队列联合使用,常用于跟踪垃圾回收状态。

垃圾回收器

Serial:{
    最基本的垃圾收集器,使用复制算法,单线程,简单高效,垃圾收集的同时,必须暂停其它所用的工作现场,直到
    收集结束,对于单个CPU环境来说,没有线程交互的开销,可获得更高的效率,是java虚拟机在Client模式下默
    认的新生代收集器。
}

ParNew:{
    是Serial收集器的多线程版本,也使用复制算法,使用多线程进行回收,收集过程中通用也要暂停其它工作线程
    是很多java虚拟机在Server模式下的新生代默认垃圾收集器。
}

Parallel Scavenge:{
    多线程,使用复制算法、高效,也是也新生代收集器,高吞吐量提交CPU利用率。使用与后台运算而不需要太多交
    互的任务,尽快的完成程序的运算任务。
}

Serial Old:{
    Serial 的老年代版本,使用标记整理算法,作为老年代使用CMS收集齐的备用方案。
}

Parallel Old:{
    Parallel Scavenge 的老年代版本,使用多线程的标记整理算法,为了在老年代同样提供吞吐量优先的垃圾
    收集器,如系统要求吞吐量较高,可使用新生代Parallel Scavenge和Parallel Old 搭配使用。
}

CMS收集器(重点):{
    Concurrent mark sweep(CMS)是一种老年代收集器,其最主要的目标是获取最短的垃圾回收停顿时间,和其它
    年老代回收器不同,它使用多线程的标记-清楚算法,最短的垃圾收集停顿时间的程序可提高用户体验。
    CMS工作四阶段:{
        初始标记:标记下GC Roots能直接关联的对象,速度很快
        并发标记:进行GC Roots跟踪的过程,和用户线程一起工作,无需暂停工作线程
        重新标记:为了修正在并发标记期间,因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录
        并发清除:
               清除 GC Roots 不可达对象,和用户线程一起工作,不需要暂停工作线程。
               由于耗时最长的并发标记和并发清除过程中,垃圾收集线程可以和用户现在一起并发工作,
               所以总体上来看CMS 收集器的内存回收和用户线程是一起并发地执行
    }
}

G1收集器(重点):{
    Garbage first是目前垃圾回收器理论发展的最前言成果,相比CMS收集器,G1收集器两个最突出的改进是:
    1.基于标记-整理算法,不产生内存碎片。
    2.精准控制回收停顿时间,在不牺牲吞吐量的前提下,实现高效垃圾回收。
     G1 收集器避免全区域垃圾收集,它把堆内存划分为大小固定的几个独立区域,并且跟踪这些区域
     的垃圾收集进度,同时在后台维护一个优先级列表,每次根据所允许的收集时间,优先回收垃圾
     最多的区域。区域划分和优先级区域回收机制,确保 G1 收集器可以在有限时间获得最高的垃圾收
     集效率
}

JVM类加载机制

JVM类加载,分为五部分:加载、验证、准备、解析、初始化;

加载:这个阶段会在内存中生成一个代表这个类的class对象。

验证:是为了确保 Class 文件的字节流中包含的信息是否符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。

准备:是正式为类变量分配内存并设置类变量的初始值阶段,即在方法区中分配这些变量所使用的内存空间。
     public static int a = 123; 这是在准备阶段是赋值是0而不是123;
     public static final int b = 123; 这个会被赋值成123;

解析:段是指虚拟机将常量池中的符号引用替换为直接引用的过程,符号引用就是 class 文件中的CONSTANT

初始化:初始化阶段是类加载最后一个阶段,前面的类加载阶段之后,除了在加载阶段可以自定义类加载
       器以外,其它操作都由 JVM 主导。到了初始阶段,才开始真正执行类中定义的 Java 程序代码。
注意以下几种情况不会执行类初始化:
1. 通过子类引用父类的静态字段,只会触发父类的初始化,而不会触发子类的初始化。
2. 定义对象数组,不会触发该类的初始化。
3. 常量在编译期间会存入调用类的常量池中,本质上并没有直接引用定义常量的类,不会触发定义常量所在的类。
4. 通过类名获取 Class 对象,不会触发类的初始化。
5. 通过 Class.forName 加载指定类时,如果指定参数 initialize 为 false 时,也不会触发类初始化,其实这    个参数是告诉虚拟机,是否要对类进行初始化。
6. 通过 ClassLoader 默认的 loadClass 方法,也不会触发初始化动作。

类加载器

三种加载器:
启动类加载器(Bootstrap ClassLoader)
    负责加载 JAVA_HOME\lib 目录中的xx.jar

扩展类加载器(Extension ClassLoader)
    负责加载 JAVA_HOME\lib\ext 目录中的

应用程序类加载器(Application ClassLoader):{
    负责加载用户路径(classpath)上的类库。JVM 通过双亲委派模型进行类的加载,
    当然我们也可以通过继承 java.lang.ClassLoader实现自定义的类加载器。
}
双亲委派是什么?
    当一个类收到了类加载请求,他首先不会尝试自己去加载这个类,而是把这个请求委派给父
类去完成,每一个层次类加载器都是如此,因此所有的加载请求都应该传送到启动类加载其中,
只有当父类加载器反馈自己无法完成这个请求的时候(在它的加载路径下没有找到所需加载的
Class),子类加载器才会尝试自己去加载。
    采用双亲委派的一个好处是比如加载位于 rt.jar 包中的类 java.lang.Object,不管是哪个加载
器加载这个类,最终都是委托给顶层的启动类加载器进行加载,这样就保证了使用不同的类加载
器最终得到的都是同样一个 Object 对象。

“JVM的学习笔记”的5,541个回复

  1. Pingback: cheap viagra 100
  2. Pingback: cialis 20 coupon
  3. Go to 1this website to see how to get diamonds on cooking fever

    gh45kkm
    The game is a lot more fun when you have as many diamonds as you want.If you enjoy mobile games like this you ought to check out the website above

  4. You’re always only one or two clicks away from a porn video that suits your exact taste so that’s an amazing feat by itself. asian big tit milfs Our search engine collects the most effective new free porn videos from pornhub, txxx, hdzog, hotmovs, xvideos and lots of others free porn tube site hd on asianporn.

  5. Pingback: cialis 80 mg dosage
  6. Hi there would you mind letting me know which hosting company you’re utilizing?
    I’ve loaded your blog in 3 different web browsers and I must
    say this blog loads a lot faster then most. Can you recommend a good web
    hosting provider at a honest price? Kudos, I appreciate it!

  7. Whores from around the world are able to show a master class in the bed and satisfy any man with all the narrow holes, taking sperm in mouth and within the hairy pussy. big tit asians xxx com is a spot where which you could share and watch Japanese porn videos, download the videos and enjoy them each time you like.

  8. Pretty section of content. I just stumbled upon your
    weblog and in accession capital to assert that I get actually enjoyed
    account your blog posts. Anyway I will be subscribing to
    your feeds and even I achievement you access consistently fast.

  9. Wow that was odd. I just wrote an incredibly long comment but after
    I clicked submit my comment didn’t appear. Grrrr…
    well I’m not writing all that over again. Regardless, just
    wanted to say excellent blog!

  10. Pingback: 匿名
  11. fantastic publish, very informative. I’m wondering why the other specialists of this sector don’t understand this.
    You must proceed your writing. I’m sure, you’ve a great readers’ base already!

  12. Pingback: 匿名
  13. Pingback: 匿名