jvm基础知识点

参考文章:

看完这篇垃圾回收,和面试官扯皮没问题了

什么是JVM? JVM和一些相关概念的关系
  • jvm中文全称为java虚拟机 是java字节码运行的平台
  • jvm和jdk、jre的关系:
    • jre是java最小运行环境,包含JVM和java核心类库
    • jdk是java最小开发环境由jre和java工具组成
JAVA内存模型
  • 公有数据区,线程共享

    • 堆:存放对象,静态变量 是垃圾回收的发挥作用的区域
    • 方法区(java8以前):存放类信息,常量池
  • 私有数据区,线程私有

    • jvm栈/虚拟机栈
      • 每个线程有一个jvm栈,存储帧
    • PC寄存器 记录线程运行到达的位置(指令地址)
    • 本地(native)方法栈:本地方法不由JVM管理
  • 本地内存 /堆外内存

    • 直接内存
    • 元空间
      • 方法区(java8以后)
垃圾回收(GC)
  • 什么是垃圾?

    • 即无法被使用的变量
  • 识别垃圾

    • 引用计数

      • 对象被引用一次,计数+1,引用次数为0,就可以回收

      • 例子:String s= new String(“dpz”); //此时引用计数为1

        • ​ s=null; //此时引用计数为0
      • 问题:循环引用 例子是转载的

      • 下面这个类包含一个自身类型的非static变量,运行到最后 a、b的引用计数都为1,可实际上a、b已经无法使用了!

      • public class TestRC {

        TestRC instance;
        public TestRC(String name) {
        }

        public static void main(String[] args) {
        // 第一步
        ​ A a = new TestRC(“a”);
        ​ B b = new TestRC(“b”);

        // 第二步
        ​ a.instance = b;
        ​ b.instance = a;

        // 第三步
        ​ a = null;
        ​ b = null;
        ​ }
        }

    • 可达性分析

      • 引用链的方式判断对象是否存活
        • 从被称作GC ROOT的对象出发,指向下一个节点
        • 当一个对象不在任意一条引用链上时,这个对象即为垃圾
        • GC ROOT是什么?如何指?
          • 以下几种对象可以作为GC ROOT
            • 虚拟机栈(栈帧中的本地变量表)中引用的对象
              • 示例代码中,a作为GC ROOT指向对象,a指向空后,对象不在链上,成为垃圾
            • 方法区中类静态属性引用的对象
              • 下面的例子,s作为GC ROOT 对象存活
              •     public static Test s;
                    public static  void main(String[] args) {
                	Test a = new Test();
                	a.s = new Test();
                	a = null;
                    }
                }
                
            • 方法区中常量引用的对象
            • 本地方法栈中 JNI(Native 方法)引用的对象
  • 垃圾回收算法

    • 标记清除法
      • 流程
        • 标记可回收对象(垃圾)
        • 回收
      • 问题:内部碎片 //连续内存
    • 复制算法 为了解决标记清除的内部碎片问题
      • 流程
        • 把内存分为两块 A和B
        • A使用标记清除后,再把对象复制到B(连续排列)
        • AB身份反转
      • 问题:
        • 内存直接少了一半 太浪费了
        • 还得来回复制对象 效率太低了
    • 标记整理(压缩)
      • 在标记清除后,将内存中的对象都排列到一起,去除碎片
      • 问题:效率太低了
    • 分代收集
      • 将堆区域分为几“代”,用不同的方式回收
        • 老年代和新生代(默认比例2:1),java8之前还有永久代
        • 新生代分为Eden区 from Survivor区(S0) to Survivor区(S1)(8:1:1)
        • 新生代的回收称为Young GC或Minor GC,老年代的回收称为Old GC或full GC
        • 老年代一般使用标记整理算法回收
      • 为什么这样做?
        • 大部分对象生命周期很短,很快就被回收了
      • 如何分配对象
        • 对象首先分配在新生代的Eden区
        • Eden区使用比例到达阈值时,触发Minor GC (大部分对象被回收)
        • 经过Minor GC后Eden区留下的对象被放到S0区,对象年龄(Minor GC次数)+1
        • 下一次Minor GC时,Eden区和S0区存活的对象一起移到S1区,对象年龄+1,S0 S1身份互换
        • 再次触发Minor GC重复上一步
        • 当对象年龄达到阈值,从S0(S1)移动到老年代
        • *当某个对象需要大量连续内存的时候会直接分配在老年代,否则来回移动开销较大
        • 在 S0(或S1) 区相同年龄的对象大小之和大于 S0(或S1)空间一半以上时,则年龄大于等于该年龄的对象也会晋升到老年代。//空间不足
      • 问题:
        • stop the world(STW)
          • 啥是STW? 顾名思义,只有GC线程在工作,其他线程挂起(stop) //在生产中出现这种情况可不好哦 服务器直接不响应请求了
          • 老年代满了,触发Full GC 同时回收老年代和新生代,导致STW,开销大
  • 垃圾收集器

    • 新生代
      • Serial
      • ParNew
      • Parrallel Scavenge
    • G1
    • 老年代
      • CMS
      • Parallel Old
      • Serial Old

    待续…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值