JVM 相关基本概念和调优

一. 内存模型详解

1. 内存模型

 

2. 元数据空间组成 

初始化的对象,成员变量 (那种非 static 的变量)所有的对象实例和数组都要在堆上分配  

新生代

(1/3)

Eden

(伊甸)区 

用来分配新的对象内存
Survivor 区from  区用于GC时的复制.
to 区
老年代(2/3)

方法区/

元空间

主要是存储类信息,常量池( static 常量和 static 变量)编译后的代码(字节码)等数据

永久代--->Metaspace(Java8 )Metaspace:与堆不相连的本地内存
  栈(线程栈)

栈的结构是栈帧组成的,每个方法在执行时就压入一帧,帧上面存储局部变量表,操作数栈,方法出口等信息,局部变量表存放的是 8 大基础类型加上一个应用类型,所以还是一个指向地址的指针

本地方

法栈

主要为 Native 方法服务

程序

计数器

记录当前线程执行的行

1.2. 内存模型

2.堆工作过程

 

3. 堆工作过程           

        (1) 为什么需要两个Survivor区呢?

      因为复制后Survivor from区虽然现在很整齐,没有碎片,当下一次进行回收时,Eden区和Survivor from区里都存在需要回收的对象,则Survivor from区也会出现碎片。 

        (2) 工作过程

       1. 新创建的对象会被放在Eden区;对于大对象直接进入老年代,实际上是为了保证Eden区具有充足的空间可用的一种策略,采用-XX:PretenureSizeThreshold参数可以设置多大的对象可以直接进入老年代内存区域
        2. 当Eden区中已使用的空间达到一定比例,会进行一次Minor GC操作,将Eden区进行回收,此时判断存活的对象会被复制进入Survivor from区(年龄加1)
        3. from区快满的时候,会将仍然在使用的对象转移到to区(年龄加1);to区进行GC回收时候仍然在使用的对象再转移到from区(年龄加1)
        4 对于长期存活的对象直接进入老年代,实际上时对Eden区到Survivor区过度的一种策略,是为了保证Eden区到Survivor区不会频繁的进行复制一直存活的对象且对Survivor区也能保证不会具有太多的一直占据的内存,采用-XX:MaxTenuringThreshold=数字 参数可以设置对象在经过多少次GC后会被放入老年代(年龄达到设置值,默认为15)。

        5.当 JVM 内存不够用的时候,会触发 Full GC,清理 JVM 老年区

二、 垃圾回收机制
        1.如和判断一个对象是否存活?/ GC 的两种判定方法: 
         引用计数法: 指的是如果某个地方引用了这个对象就+1,如果失效了就-1,当为 0 就会回收但是 JVM 没有用这种方式,因为无法判定相互循环引用( A 引用 B,B 引用 A)的情况
       可达性算法(引用链法):从一个被称为 GC Roots 的对象开始向下搜索,找到的对象标记为“非垃圾对象”,如果一个对象到 GCRoots 没有任何引用链相连时,则说明此对象不可用。     

   

(1)虚拟机栈中引用的对象;  (2)方法区类静态属性引用的对象;   (3)方法区常量池引用的对象;    (4)本地方法栈引用的对象

     4)  被判定为回收的对象是否就一定被回收?

         当一个对象不可达 GC Root 时,这个对象并不会立马被回收,而是出于一个死缓的阶段,若要被真正的回收需要经历两次标记:

      (1)如果对象在可达性分析中没有与 GC Root 的引用链,那么此时就会被第一次标记并且进行一次筛选,筛选的条件是是否有必要执行 finalize()方法。当对象没有覆盖 finalize()方法或者已被虚拟机调用过,那么就认为是没必要的。如果该对象有必要执行 finalize()方法,那么这个对象将会放在一个称为 F-Queue 的对队列中,虚拟机会触发一个 Finalize()线程去执行,此线程是低优先级的,并且虚拟机不会承诺一直等待它运行完,这是因为如果 finalize()执行缓慢或者发生了死锁,那么就会造成 FQueue 队列一直等待,造成了内存回收系统的崩溃。

         (2)GC 对处于 F-Queue 中的对象进行第二次被标记,这时,该对象将被移除”即将回收”集合,等待回收。

    5) SafePoint 
        比如 GC 的时候必须要等到 Java 线程都进入到 safepoint 的时候 VMThread 才能开始执行 GC,
       (1) 循环的末尾 (防止大循环的时候一直不进入 safepoint,而其他线程在等待它进入safepoint)
     (2) 方法返回前
       (3) 调用方法的 call 之后
       (4) 抛出异常的位置

    6)java中垃圾收集方法
        标记清除:标记完毕之后再清除,效率不高,会产生碎片   

        标记整理:标记完毕之后,让所有存活的对象向一端移动

        复制策略:将原来存在的内存分为两个相等的区,使用一块进行新生代的内存分配,当要GC时,则将存活的对象复制进入另一块空闲的内存,然后将使用的内存进行清除,从而又有一个空闲区和一个使用区,并且不会有碎片问题。

        分代收集:现在的虚拟机垃圾收集大多采用这种方式,它根据对象的生存周期,将堆分为新生代和老年代。在新生代中,由于对象生存期短,每次回收都会有大量对象死去,那么这时就采用复制算法。老年代里的对象存活率较高,没有额外的空间进行分配担保,可以使用标记-整理 或者 标记-清除。

 3.GC 收集器有哪些? CMS 收集器与 G1 收集器的特点。
     并行收集器:串行收集器使用一个单独的线程进行收集, GC 时服务有停顿时间
     串行收集器:次要回收中使用多线程来执行
    CMS收集器:是基于“标记—清除”算法实现的,经过多次标记才会被清除 ;

    G1 从整体来看是基于“标记—整理”算法实现的收集器,从局部(两个 Region 之间上来看是基于“复制”算法实现的

4. 几种常用的内存调试工具
     jstack 可以看当前栈的情况, jmap 查看内存, jhat 进行 dump 堆的信息

5. 类加载

   1)类加载的几个过程:

     (1)装载

         查找并加载java类的二进制数据(.class文件)

      (2)链接

        a.验证:验证字节码的准确性,防止高手修改.class文件,确保加载类正确性

        b.准备:将静态变量分配内存,并将其初始化为默认值

        c.解析:将类中的符号引用转换成直接引用

       (3)初始化

        a.创建类实例(new)

        b.访问某个类或接口的静态变量,并将类的静态变量赋予正确的初始值

        c.调用类的静态方法

        d.反射

        e.初始化一个类的子类(首先初始化父类)

         f.JVM启动时标明的启动类,文件名和类名相同的那个类  

  2)类加载器分类

     (1)根类加载器(Bootstrap classLoader):负责加载lib下的核心类库
     (2)扩展加载器(ExtClassLoader):负责加载lib目录下的ext的jar类包
     (3)应用加载器(AppClassLoader):负责加载ClassPath路劲下的类包(自定义的类)
     (4)自定义类加载器:继承ClassLoader,重写loadClass(),findClass(),一般是只需要重写findClass

  3)类加载器双亲委派机制

     (1.保证类的唯一性 2、沙箱安全机制)
    a.先检查指定的类是否已经加载过了,若已经加载过,则直接返回加载的类
    b.若没有加载,则判断有没有父类,有的话则调用父类加载器,或者调用根类加载器加载。
    c.若父类加载器与根类加载器都没有找到指定的类,则调用自身的findClass来完成类加载

 4)JVM怎样判断两个类是否相同

  java 虚拟机不仅要看类的全名是否相同,还要看加载此类的类加载器是否一样。只有两者都相同的情况,才认为两个类是相同的。即便是同样的字节代码,被不同的类加载器加载之后所得到的类,也是不同的

6.java 内存模型

     详细看这篇文章:Java多线程(三) —— 可见性问题和JMM_多线程可见性问题-CSDN博客  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值