• 笔记-jvm学习


    类加载

    类加载子系统的作用

    ClassLoader的角色

    类加载过程: 加载->链接->初始化

    加载


    链接

    初始化



    其中number会在链接阶段的准备阶段会初始化为0 ,然后到初始化阶段执行clinit时先将变量赋值20然后再赋值为10
    注意:如果没有类变量,则字节码文件中不会存在clinit方法
    eg:

    类加载器分类





    String加载器是使用引导类加载器加载
    注: java核心类库都是使用引导类加载器加载的

    引导类加载器

    扩展类加载器

    应用程序加载器

    获取加载类的路径


    需要自定义加载类的情况

    隔离加载类:在某些框架需要使用中间件,但是中间件有自己的框架,在一个项目中同时引入多个框架可能导致冲突,主要是指路径相同,名称相同的类避免冲突
    修改类加载的方式: 动态加载用到
    扩展加载源: 有可能从数据库中加载类
    防止源码泄露: java代码容易被反编译

    自定义加载类实现步骤:


    重写findClass()方法

    如果没有复杂需求可以直接继承URLClassLoader

    双亲委派机制


    如果定义了一个跟和核心类一样的包和路径,就不会执行,还是执行核心类

    eg:

    当app加载类接收到加载请求时,它会向上委托,如果还有父加载器,则继续向上委托
    如果父类中能找到对应的类,就完成加载,如果没有找到,则最后让子类加载
    eg:

    因为这个类要执行main方法,就要一层层往上找
    当找到核心类String就加载了,结果核心类中的String没有main方法,所以报错
    优点

    沙箱保护机制

    两个对象相等

    类的主动使用和被动使用

    运行时数据区

    内存布局

    具体划分

    一个jvm实例对应一个runtime对象

    线程

    程序计数器(PC寄存器)


    作用:存储指向下一条指令的地址,由执行引擎读取下一条指令
    线程私有的,每个线程都有一个

    final关键字

    ++x涉及到改变x的值,所以会报错,而x+1不会修改x的值,所以不会报错


    o声明为final不能再变,但是对象里面的属性可以变

    使用pc寄存器存储字节码指令地址有什么用

    为什么使用pc寄存器记录当前线程的执行地址

    cpu时间片

    虚拟机栈

    虚拟机栈概述

    栈是运行时的单位,而堆是存储时的单位
    栈解决程序运行问题,程序如何执行,或者如何处理数据,堆解决的是数据的存储问题,即数据如何放,放哪里

    栈中可能出现的异常

    设置栈大小

    -Xss 设置最大栈空间

    栈的存储单位

    每个线程都有自己的栈, 栈中的数据都是以栈帧的格式存在




    栈帧内部

    局部变量表



    局部变量表中的变量是重要的根节点,只要被局部变量表中直接或者间接引用的对象都不会被回收

    操作数栈



    动态链接

    方法的调用




    非虚方法

    方法调用: 虚方法与非虚方法

    动态语言和静态语言

    方法返回地址


    本地方法栈


    堆核心概述



    设置堆内存大小与OOM

    MinorGC MajorGC FullGC

    MinorGC发生时间

    老年代GC

    内存分配策略

    TLAB




    堆空间参数设置


    如果edgen区设置的过大,容易导致s0和s1区装不下回收后还剩下的对象
    容易导致对象没有达到阈值就进入老年区了
    如果edgen区设置的过小,容易导致垃圾回收的次数过多

    空间分配担保

    堆是分配对象存储的唯一选择吗


    逃逸分析可以使对象分配到栈上,减少堆上垃圾回收的时间



    代码优化之同步省略

    代码优化之标量替换




    方法区

    运行时数据区结构图


    从线程共享与否的角度看

    栈,堆,方法区的交互关系

    方法区的理解



    设置方法区大小与OOM



    如何解决OOM


    方法区内部结构


    类型信息

    域信息

    方法的信息

    运行时常量池

    常量池,可以看做是一张表,虚拟机指令根据这张常量表找到要执行的类名,方法名,参数类型,字面量等类型

    方法区演进细节




    方法区的垃圾回收

    对象实例化

    对象创建步骤


    直接内存

    好处

    缺点

    执行引擎

    执行引擎概述

    执行引擎工作过程


    java代码编译和执行过程


    JIT编译器





    String的不可变性


    intern使用

    垃圾回收

    标记阶段

    对象存活判断

    引用计数算法


    java没有使用这种算法
    如果使用这种算法,则下图就会出现垃圾没有回收的现象



    可达性分析算法









    分析prof文件

    清除阶段

    标记-清除算法


    缺点:

    复制算法




    标记-压缩算法





    对比

    分代收集算法



    分区算法:将所有的内存分成一个一个块


    垃圾回收相关概念

    System.gc()

    内存溢出OOM




    内存泄漏



    stop the world



    安全点与安全区域




    安全区域

    引用



    软引用:内存不够即回收,常用于高速缓存

    弱引用:发现即回收

    虚引用

    终结器引用

    垃圾回收器

    垃圾回收分类



    按照工作模式区分:


    评估GC性能指标

    7款经典的垃圾回收器



    组合关系



    jinfo查看信息

    Serial回收期:串行回收



    优点

    现在只有单核的cpu才会用串行的收集器,一般都不再使用

    ParNew回收期:并行回收


    ParNew除了并行之外,跟串行的收集器没有啥区别
    新生代用并行方式,老年代用串行方式


    Parallel Scavenge回收期:吞吐量优先



    java8默认的垃圾收集器

    参数设置



    CMS回收期:低延迟


    CMS工作原理









    总结

    G1回收器:区域化分代式


    为什么叫G1



    优点:








    适用场景

    分区Region:化整为零


    大对象区:

    G1回收器垃圾回收过程



    G1垃圾回收垃圾过程




    年轻代





    G1优化建议

    垃圾回收器总结




    垃圾回收器的选择

    GC日志分析






    ZGC的了解


    Class文件结构

    类文件结构有哪几个部分

    1.魔数
    2.Class文件版本号
    3.常量池
    4.访问标识
    5.类索引,父类索引,接口索引
    6.字段表集合
    7.方法表集合
    8.属性表集合

    1.魔数 : CAFEBABY

    2.Class文件版本号:

    3.常量池


    常量池表项中,用于存放编译时期生成的各种字面量和符号引用,这部分内容在类加载后进入方法区的运行时常量池存放
    常量池计数器




    4.访问标识


    5.类索引,父类索引,接口索引

    6.字段表集合

    7.方法表集合

    8.属性表集合

    javap




    字节码指令概述



    加载指令

    操作数栈

    局部变量表

    常量入栈指令

    类的生命周期

    基本数据类型由虚拟机定义
    引用类型需要进行类的加载


    验证

    主动使用和被动使用

    类的卸载

    类加载器


    不同加载器加载的对象不是同一个对象





    引导类加载器

    拓展类加载器

    应用类加载器

    自定义类加载器

    获取类加载器

    热替换


    沙箱安全机制






    性能调优

    1.发现问题: 性能监控

    GC频繁
    cpu load过高
    OOM
    内存泄漏
    死锁
    程序响应时间过长

    2.排查问题: 性能分析

    打印GC日志,通过GCviewer分析日志信息
    灵活运用命令行,jstack,jmap,jinfo
    dump导出堆文件,使用内存分析工具分析文件
    使用阿里Arthas或jsonsole实时查看jvm状态
    jstack查看堆栈信息

    3.解决问题: 性能调优

    适当增加内存,根据业务背景选择垃圾回收器
    优化代码控制内存使用
    增加机器,分散节点压力
    合理设置线程池线程数量
    使用中间件提高程序效率,比如增加缓存,消息队列等

    jps


    jstat


    jinfo

  • 相关阅读:
    设计模式学习总结系列应用实例
    【研究课题】高校特殊学生的发现及培养机制研究
    Linux下Oracle11G RAC报错:在安装oracle软件时报file not found一例
    python pro practice
    openstack python sdk list tenants get token get servers
    openstack api
    python
    git for windows
    openstack api users list get token get servers
    linux 流量监控
  • 原文地址:https://www.cnblogs.com/Baronboy/p/14598406.html
Copyright © 2020-2023  润新知