JVM相关知识整理

JVM相关知识整理

个人理解之后简单整理,除去了一些不是很重要的部分,把语句整理的很简洁。

类加载

  1. 加载

    class文件变为二进制流加载到内存里,变为动态的Class实例

  2. 链接

    1. 验证

      验证字节码格式是否符合虚拟机规范

    2. 准备

      对于静态变量分配内存和赋值零值的过程。

    3. 解析

      将常量池的符号引用替换为直接引用的过程。

      解析类和方法确保类和类之间相互引用的正确性

  3. 初始化

    收集类中静态变量的赋值操作自动生成clinit方法并执行。

类加载时机

  1. 遇到new关键字,会先检测是否这个类被加载
  2. 通过反射创建对象时
  3. 创建子类对象时如果父类没有被加载会先加载父类。
  4. 引用类的静态变量或静态方法

那么通过子类来引用父类的静态字段,会初始化子类和父类吗?

会初始化父类,但是不会初始化子类。因为是子类引用父类,只有在用到子类时才会初始化子类。

如果创建一个对象的数组类型,会初始化这个类吗?比如Person[] arr = new Person[10]

不会。只有在实际用到这个类时才会初始化这个类。

双亲委派模型介绍一下

双亲委派模型主要是这样的。

一个类收到加载请求后会先看

  1. 待加载的类是否已经被加载过,如果已经被加载过,返回
  2. 如果没有被加载过,会先询问上层的类是否可以加载
  3. 上层类收到加载类的请求也是做相同的处理,直到根类加载器
  4. 如果上层的类可以加载,就由上层的类加载该类,返回加载好的Class对象,否则,抛出异常,由下层类捕获异常并且尝试加载这个类。

双亲委派模型可以保证:

  1. 类加载的一致性,不会出现已经加载的类被别的类加载器再加载一遍
  2. 核心类的加载的正确性,因为核心类都是由启动类加载器或者扩展类加载器去加载的。

不同类加载器加载的Class对象是同一个Class对象吗?

不是的,由不同类加载器加载的Class对象被分为不同的Class对象。

对象加载步骤

  1. 检查类是否加载

  2. 分配内存

    1. 分配内存两种方式:

      1. 指针碰撞

        通过指针分为两部分,一部分为空闲,另一部分为已经被使用的对象。

        每次要分配对象,把指针进行移动即可。

      2. 空闲列表

        通过空闲列表记录所有空间的空闲情况。

    2. 分配内存时保证并发安全:

      前提:如果线程A发现地址0X0001可用,线程A准备占用时,被中断了,线程B发现地址0X0001可用,直接创建对象。

      此时如果又回到线程A,那么线程A就会继续在这个地址上创建对象,会把B创建的对象覆盖掉,解决方法在下面。

      1. 给每个线程分配一块空间TLAB(线程本地分配缓存空间),创建对象先在这里创建,用完了就去堆中剩余的地方创建
      2. 堆中剩余地方可能发生上述提到的线程不安全情况,所以通过CAS来重试确保不会出错。
  3. 赋值零值

    比如int赋值为0,Object赋值为null等。

    保证对象属性不赋值就能用,方便点

  4. 创建对象头

    记录一些数据,比如

    1. hashcode
    2. GC年龄
    3. 锁标志
    4. 对象的Class对象

    等等

  5. 执行对象构造函数

JVM内存结构

  1. 几乎存储着所有的实例对象。

  2. 被线程共享。

  3. 分为新生代和老年代。

堆大小设置参数:-Xms256M -Xmx1024M(-X表示是运行参数,ms是memory start,mx是memory max)

元空间

存储的内容:类元信息,字段,静态属性,方法,常量。字符串常量已经被移动到堆

比如:Object类信息,System.out属性,整形常量560等

虚拟机栈

  1. 线程私有
  2. 用于支持方法调用
  3. 进行方法调用会进行栈帧的入栈和出栈

栈帧:

  1. 局部变量表

    1. 存放方法参数和局部变量的地方

    2. 变量不会自动初始化,必须显式初始化。

  2. 操作数栈

    1. 一个小型栈
    2. 存放计算过程中的临时变量
  3. 动态链接

    指向常量池中,该方法的引用。为了支持运行中方法的动态链接。

  4. 方法返回地址

    方法退出。

    1. 正常退出
    2. 异常退出

垃圾回收器

  1. Serial

    串行垃圾回收器

    每次回收垃圾会触发 STW(Stop The World),即长时间暂停去回收垃圾,在此期间不能执行用户线程。

  2. CMS

    目的:实现短停顿。

    可以实现和用户线程并发。

    步骤:

    1. 初始标记
    2. 并发标记
    3. 重新标记
    4. 并发清除

    13会出现STW,24不会。

    老年代采用的垃圾回收算法是:标记-清除和标记整理混合。先允许部分的空闲空间不连续,等到分配时候空间不够了,再统一挪动一次。

  3. G1

    把待回收区域分为四部分

    年轻,幸存者,老年,大对象。

    整个堆都会被分为这几部分。

    哪部分垃圾多清理哪部分。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值