JVM详情

JVM详情

一、JVM内存划分

  1. 堆:存放new出来的对象;(成员变量)

  2. 方法区:存放的是类对象;(静态变量)

  3. 栈(虚拟机栈, 本地方法栈):存放方法之间的调用关系;(局部变量)

  4. 程序计数器:存放的是下一个要执行的指令;

注意:变量存放在哪一个区域,和变量类型无关!和变量的形态(局部,成员,静态)有关!

  • a 是成员变量,在堆上
  • b 是静态变量,在方法区
  • c 是成员变量,在堆上
  • d 是静态引用对象在方法区,new 出来的对象在堆上
  • A 是局部变量,在栈上,new 出来的对象在堆上

二、双亲委派模型(重点考察)

什么是双亲委派模型?

复制代码
    一个类加载器收到类加载请求,首先自己不会加载这个类,而是把这个请求委派给父类加载器完成,每一层都是如此,因此所有加载请求最终都会送到最顶层的加载器中,只有父加载器反馈无法加载这个请求,子类才会尝试去加载;

2.4.2、涉及到的类加载器

  1. Bootstrap ClassLoader :负责加载标准库中的类;

  2. Extension ClassLoader:负责加载JVM扩展的库的类(标准库中没有,但JVM自己实现出了);

  3. Application ClassLoader :负责加载我们自己的项目中的自定义类;

三、 GC(垃圾回收机制)

复制代码
 在学习C语言的过程中,需要通过 malloc 申请内存,最后通过 free 进行释放,这里就容易存在一个问题------忘记free,造成内存泄漏;而GC(垃圾回收)就是一个主流处理方案;

垃圾的判定算法

  • 可达性分析(JVM采用)

    复制代码
     顾名思义,就可以到达的变量
     约定一些特定的变量,成为 "GC roots", 每隔一段时间,从 GCroots 出发,进行遍历,查询哪些变量是能够被访问到的,能被访问到的变量就称为 "可达",否则就是 "不可达"
     
     -- 栈上的变量;
    
     -- 常量池引用的对象;
    
     -- 方法区中静态属性引用对象;
    
     -- 方法区中常量引用的对象;
  • 引用计数

    复制代码
     每多一个引用指向该对象,计数器就+1;
     每少一个引用指向该对象,计数器就-1;
     当计数器的数值为 0 时,就说明这个对象已经没有人能够再使用了,此时就可以进行释放;
     但是如果有相互引用的情况,类似于死锁,那这个内存就永远也释放不了

垃圾回收算法

  • 标记-清除算法

    复制代码
     简单来说,就是标记出垃圾后,直接把对象对应的内存空间进行释放;
     
     但是假如释放了3块空间不连续,那么虽然内存上有3块空间,但是却new不出一个完整的2块空间
     
     引起了内存碎片问题
  • 复制算法

    这是针对内存碎片问题,引入的办法;

    复制代码
        具体的,将内存分成两块大小相等的空间,但只使用其中的一块,当需要进行垃圾回收时,就把正在使用的那块空间上还存活的对象复制到另一块上,再将使用过的那块内存全部清空;这样做的好处就是不用再考虑内存碎片问题;
     1. 空间利用率相比标记清除法更低了;
     2. 但是若一轮GC下来,大部分需要保留,只有极少数要回收,这时候复制的开销就很大了;
  • 标记整理算法

    复制代码
    标记过程与 "标记-清除算法"一致,但后续步骤不是直接对可回收对象进行清理,而是让所有存活对象都向一端连续性的覆盖,然后直接清除掉边界以外的空间;(类似于顺序表的删除元素)
  • 分代算法

    复制代码
    分代算法综合了上面所说的三种算法,通过区域划分,实现不同区域用不同的垃圾回收策略,从而实现更好的垃圾回收
    
     1. 刚创建出来的对象,进入伊甸区;
    
     2. 若新对象熬过一轮GC,没被回收,就通过复制算法,复制到生存区;
    
     3. 生存区的对象也要经历GC,每熬过一次GC,就会通过复制算法拷贝到另一个生存区(只要这个对象不死亡,就会在两个生存区来回拷贝);
    
     4. 如果一个对象在生存区中,反复坚持了很多轮还没去世,就会被放到老年代(老年代GC的频率会降低);
    
     5. 若对象来到了老年代,也会进行定期的GC,只是频率更低了;老年代采取标记整理的方式来处理垃圾;
相关推荐
এ慕ོ冬℘゜4 小时前
深入 JavaScript BOM:掌握 window 对象的窗口控制魔法
开发语言·javascript·ecmascript
2501_941982054 小时前
企业微信二次开发:如何用 Python 搭建通用的 Webhook 实时消息接收
开发语言·python·企业微信
cfm_29144 小时前
Spring监听器
java·spring boot·后端
逝水无殇4 小时前
C# 特性详解
开发语言·后端·c#
SamDeepThinking4 小时前
Java面向对象在JVM里怎么实现
java·后端·面试
灵晔君5 小时前
【C++】二叉搜索树
开发语言·c++
LongtengGensSupreme5 小时前
C#图像内存高速拷贝:使用Marshal.AllocHGlobal与ArrayPool实现内存拷贝的几个方法
开发语言·数码相机·c#
Java面试题总结5 小时前
Python,单引号和双引号有何区别
开发语言·python
鱼子星_5 小时前
【C++】内存管理:内存分布,new/delete的使用及细节处理,new/delete的底层,定位new表达式
开发语言·c++·笔记
学逆向的5 小时前
汇编——函数
开发语言·汇编·网络安全