JVM初级篇学习笔记

jvm学习笔记

  • 垃圾回收方法
    • 标识算法:把没有引用的数据标记出来,然后进行清楚,缺点就是容易造成碎片化内存
      • 引用计数算法:对每个对象保存一个整型的引用计数器属性,用于记录对象被引用的情况,只要对象的引用计数器的值为0,就可以进行回收
      • 可达性分析算法:以根对象集合为起始点,按照从上到下的方式搜索被根对象集合所连接的目标对象是否可达
    • 复制算法:把内存分成两半,把引用的数据复制到另外一半的内存中,然后清楚原来一般的内存,缺点就是造成内存浪费
    • 标记整理算法:先把没有标记的数据清楚掉,然后整理被标记的数据。缺点就是效率低
  • GC的演化 (随着内存的大小不断增长而演进)
    • Serial
    • parallel
  • JVM生命周期
    • 虚拟机的启动:是通过引导类bootstrap class loader创建个初始类来完成的
    • 虚拟机的执行:
  • 类的加载过程
    • 加载
    • 验证
    • 准备
    • 解析
    • 初始化
  • 类加载器的分类
    • BootStrap Class Loader(启动类加载器:负责加载java类的核心内库)
    • Ext Class Loader
    • App Class Loader
  • 双亲委派机制
    • 优势:避免类的重复加载,保护程序的安全,防止核心API被随意篡改
    • 沙箱安全机制:在项目中新建一个String类,写上main方法,包名是java.lang,启动项目的时候会报mian方法找不到,这样就叫沙箱安全机制,目的是保护核心API被随意篡改
  • JVM中怎么标识两个Class对象是同一个类
    • 类的完整类名必须一直,包括包名
    • 加载这个类的Class Loader必须一样
  • PC寄存器(程序计数器):存储下一条指令的地址。每隔线程都有它自己的程序计数器,是线程私有的
  • 虚拟机栈(Stacks)
    • 保存方法的局部变量
    • 保存引用对象的地址
    • 保存部分结果
    • 设置栈的大小:-Xss
  • 堆(Heap)
    • 堆中(Eden)有一块缓冲区,是不被线程共享的,每个线程独有一份
    • 初始内存是计算机物理内存的1/64
    • 最大内存是计算机物理内存的1/4
    • 新生代与老年代内存比列默认是1/2
      • Eden空间和另外两个Survivor空间比列是8 :1:1
    • 垃圾回收(GC)
      • Mi0nor GC (发生在新生代)
      • Major  GC(发生在老年代)
      • Full GC(对整个堆进行回收)
    • 堆空间常用的参数
      • Xms(初始堆的值)
      • Xmx(最大堆的值)
      • Xmn(设置新生代的大小)
      • -XX:+PrintFlagsInitial(查看所有的参数的默认初始值)
      • -XX:+PrintFlagsFinal(查看所有的参数的最终值)
    • 逃逸分析:当一个对象在方法中被定义后,对象只在方法内部使用,则没有发生逃逸,否则就是发生了逃逸
    • 字符串常量池
      • 字符串常量池在堆中的原因:如果在元空间,只有Full GC才会清除,而Full GC只有当老年代跟元空间的内存都不足才会触发,很难去触发,所以放在了堆中,有利于快速清除没用的常量,提高效率
    • 静态变量
  • 方法区(Method Area)
    • Class信息
    • 域信息
    • 方法信息
    • JIT代码缓存
    • 运行时常量池
      • 常量池是Class文件的一部分,运行时常量池是对常量池的引用
  • 对象创建的六个步骤
    • 判断对象对应的类是否加载,链接,初始化
      • 虚拟机遇到new的指令。先去元空间的常量池中定位一个类的引用,看看这个类是否被加载,解释,初始化,如果没有,那么在双亲委派的机制下,通过对应的类加载器去加载。如果没有找到对应的类,那么就会报ClassNotFoundException。
    • 为对象分配内存
    • 处理并发安全问题
    • 初始化分配到空间
    • 设置对象的对象头
    • 执行init方法进行初始化
  • 对象在内存中的布局
    • 对象头
      • 运行时元数据
        • 哈希值
        • GC分代年龄
        • 锁状态标志
        • 线程持有的锁
        • 偏向线程id
        • 偏向时间戳
      • 类型指针:指向类元数据,确定该对象所属的类型
    • 实例数据
    • 对齐填充
  • 直接内存
    • 在java堆外,是直接向系统申请的内存区域。来源于NIO
    • 访问性能比堆高
    • 可以用过MaxDirectMemorySize设置内存大小
    • 如果不指定,默认与堆的最大值 -Xmx一样
  • 执行引擎:执行jvm解析的字节码文件对应的指令
    • JIT编译器:
    • 字节码解释器:将字节码文件中的内容翻译为对应平台的本地机器指令执行
    • -Xint: 完全采用解释器模式执行程序
    • -Xcomp:完全采用即时编译器模式执行程序,如果即时编译器出现问题,解释器会介入执行
    • -Xmixed:采用解释器+即时编译器的混合模式共同执行程序
  • StringTable(字符串常量池)
    • 字符串常量池中是不会存储相同内容的字符串,
    • 是个固定大小的HashTable结果,通过-XX:StirngTableSize可以改变大小,1009是可以设置的最小值
    • HashTbale短,性能差
    • 常量跟常量相加,是在常量池中发生的
    • 变量(引用类型)跟字符串相加,相当于在堆中new String()
    • intern
      • String s = new String("1")
        • 这个是在堆中new了一个对象,在字符串常量池中存放了"1"
        • s.intern()这个方法此时没啥用,在调用此方法前,字符串常量池中已经存了"1"
      • String s2 = new String("1") + new String("1")
        • 此时在字符串常量池中没有"11",原因是引用类型相加,相当于是new Stringbuild对象,然后用append()方法相加,此过程是在堆中进行的。
        • s2.intern(),此时在字符串常量池中生产了"11"
      • 如果字符串s在字符串常量池中存在对应字面量,则intern()方法返回该字面量的地址;如果不存在,则创建一个对应的字面量,并返回该字面量的地址
    • String的垃圾回收
      • -XX:+PrintStringTableStatistic -XX:+PrintGCDetails
  •  内存泄露
    • 只有对象不会在被程序用到了,但是GC又不能回收他们的情况,才叫内存泄露
  • P170.待续。。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值