《JavaEE初阶》JVM基础知识

这篇具有很好参考价值的文章主要介绍了《JavaEE初阶》JVM基础知识。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

《JavaEE初阶》JVM基础知识

本章主要介绍JVM中比较重要的三个内容:

  • JVM内存区域划分

  • JVM类加载机制

  • JVM垃圾回收机制

JVM内存区域划分

当我们创建一个java进程时,启动时会向操作系统申请一块内存,JVM会将这块内存划分为几个区域: 堆 栈 程序计数器 方法区

堆:

堆上主要存放的是new的对象,是最重要的区域,也是内存划分最多的区域.

栈:

栈上主要存放 方法之间的调用关系(不记录方法的主要内容,只记录方法之间的调用关系),局部变量

JVM中的栈分为java虚拟机栈和本地方法栈,java虚拟机栈是java代码使用的栈,而本地方法栈主要存放JVM内部使用的C++代码,(我们在阅读源码时,可以看到native方法,这类方法就是由JVM内部通过C++来实现的).但是在java1.8中,将这两块区域进行合并.

方法区:

方法区中主要存放 类对象

类对象: 类对象是我们在编写代码中,类的代码以及类中的静态变量与静态方法,这都属于类对象中的内容.

class student{
    int a;            //对象内容  每个对象都有一份a
    static int b;    // 类对象内容  所有对象共用一份b
}

程序计数器:

这个区域主要存放 下一条指令 的地址,这块区域内存划分最小的区域.

划分细节:

方法区和堆,在整个java进程中,只有一份,而栈和程序计数器是每一个进程都具有的.

《JavaEE初阶》JVM基础知识

类加载机制:

对于一个java程序,JVM通过类加载机制了类的生命周期:

《JavaEE初阶》JVM基础知识

分为以下三个大的步骤:

  • 加载:

    java程序打开.class文件,将.class文件转化为二进制的字节流,将这个二进制字节流的静态存储结构转化为方法区运行时的数据结构.在内存中生成一个代表这个类java.lang.class对象

  • 链接:

    1. 验证:

      检查.class文件格式是否符合规范要求

    2. 准备:

      给静态变量分配内存空间,并将其值填充为 0 值

    3. 解析:

      将字符串常量进行初始化, “符号引用替换为直接引用”

      在编译过程中,编译器会通过一些特殊的符号来代表这些字符串常量,在进行类加载时,将真正的字符串常量存放到对应内存中.

  • 初始化:

    针对类的静态成员进行初始化,执行静态代码块.

双亲委派模型:

描述的是类加载阶段,JVM去那些目录下寻找.class文件.

JVM自带的三个类加载器:

  • BootStrapClassLoader 负责加载标准库中的类

  • ExtensionClassLoader 负责加载一些扩展的类

  • ApplicationClassLoader 负责加载本地程序中的类

双亲委派模型就是在上述体系中实现的:
《JavaEE初阶》JVM基础知识

双亲委派模型能够巧妙地避免我们在本地程序中写出一个特殊的类,导致将方法库中的类给覆盖掉.例如我们写了个java.lang.String…

垃圾回收机制(GC)

在我们学习C语言的时候,我们知道C语言中申请内存是需要手动通过free来释放的.对于需要程序员手动释放内存,是容易造成内存泄露的.

JVM为java实现了自动化进行内存释放,也就是垃圾回收机制(GC)

什么样的内存需要GC来回收

在了解GC之前,我们需要了解什么样的内存需要被回收:

对于程序计数器而言,每一个进程中都具有一个程序计数器,所以我们不需要进行GC,直接跟随进程销毁即可

对于栈而言,栈中主要存储的是局部变量,我们已经约定了局部变量在出了其作用域就可以会被回收, 所以也不需要GC.

对于方法区而言,其主要任务是进行类加载,很少设计到"类卸载",所以对于GC的使用并不是很急迫.

对于堆而言,堆存储了许多new 对象, 这也意味着当很多对象使用完之后,是需要GC来清理内存的,故而堆是GC工作的主战场.

引用计数来判断对象是否是垃圾:

引用计数方案并不是java使用的方法.但我们也需要了解.

引用计数就是在一个对象中引入额外的计数器,这个计数器记录了有多少个引用指向了这个对象.如果计数器的值为0,说明该对象没有引用指向,则认为是垃圾,需要释放.

这个方案是具有很多缺陷的:

  1. 在多线程场景下需要考虑线程安全问题,(如果了解过多线程会很容易理解为什么有线程安全问题)

  2. 如果对象占用的内容较小,并且有多个时,会带来空间资源的浪费.(如果对象是2kb,引入计数器后变成了4kb,负担就翻倍了)

  3. 循环引用问题:

    class Test{
        Test ref = null;
    }
    Test a = new Test();   
    Test b = new Test();
    a.ref = b;
    b.ref = a;
    

    《JavaEE初阶》JVM基础知识

    如果我们把a,b的引用销毁,我们想要的效果是 两个Test被销毁,但是事与愿违:

    《JavaEE初阶》JVM基础知识

    此时计数器为1,仍然不能销毁这个对象.

使用可达性分析来判断对象是否为垃圾:

可达性分析是java使用的方案.

可达性分析是通过一些特殊的变量为起点.从起点出发,看看哪些对象可以被访问到,如果可以呗访问到,则认为这个对象不是垃圾,如果不能访问到,则认为是垃圾.

可以树的构造思想来理解:

《JavaEE初阶》JVM基础知识

以A结点为起点,则认为对象BDEG不是垃圾,CF是垃圾.

可达性分析相比于引用计数,就不会占用额外的内存空间,也不会涉及到循环引用问题.

垃圾回收策略:

有缺陷的垃圾回收策略:
  1. 标记-清除策略:

    使用可达性分析,找到垃圾对象,直接将垃圾对象释放掉.

    《JavaEE初阶》JVM基础知识

    将图中的垃圾对象进行回收

    这个方案的确将内存释放了.但是也引入了一个很严重的问题,释放后的内存空间并不是连续的.即内存碎片问题.

  2. 标记-复制策略:

    使用可达性分析,找到垃圾对象,将要保留的对象复制到另一侧的内存空间.

    《JavaEE初阶》JVM基础知识

    这样就不会造成内存碎片问题,但是也导致了内存空间的不合理利用.使得内存空间的利用率大大降低.

  3. 标记-整理策略:

    使用可达性分析,找到垃圾对象,使用顺序表或者链表的思想将垃圾对象调整内存位置.解决内存碎片问题.

    这个方案可以提高内存的利用率,也可以解决内存碎片的情况,但是缺点也十分明显,搬运操作是O(n)时间复杂度,比较耗时.

上述操作都有各自的缺陷,但是JVM将上述方案进行了结合,使用分代回收方案来解决他们各自的缺陷:

JVM使用的分代回收策略:

将内存空间划分为以下三种区域:
《JavaEE初阶》JVM基础知识

采用以下方案来操作对象:

  1. 新new的对象放在伊甸区

  2. 伊甸区的对象是大概率撑不过第一轮GC的,如果伊甸区的对象撑过了第一轮GC,则将这个对象通过复制算法放在幸存区.

  3. 幸存区的对象经过又一轮GC,如果幸存区的对象撑过了这一轮GC,则将这个对象通过复制算法放入另一个幸存区.

  4. 当对象在幸存区经过多轮GC,依然没有被垃圾回收,则认为这个对象一时半会是不会被销毁的,所以将这个对象通过复制算法放到老年代.

  5. 对象在老年代空间中,也是需要经过GC,但是GC的频率大大降低,如果老年代中的对象被标记为垃圾对象,则使用标记整理方案来进行回收.(由于老年代被垃圾回收的频率不高,所以可以接受标记整理方案带来的时间开销.)

  6. 当有一个很大的对象时,是直接存入到老年代的.(JVM特殊规定)文章来源地址https://www.toymoban.com/news/detail-486019.html

到了这里,关于《JavaEE初阶》JVM基础知识的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java面试指导-JavaEE基础知识

    1. JDK 和 JRE 有什么区别? JDK:Java Development Kit 的简称,Java 开发工具包,提供了 Java 的开发环境和运行环境。 JRE:Java Runtime Environment 的简称,Java 运行环境,为 Java 的运行提供了所需环境。 具体来说 JDK 其实包含了 JRE,同时还包含了编译 Java 源码的编译器 Javac,还包含了很

    2024年02月12日
    浏览(36)
  • JVM-基础知识

    JVM基础知识 JVM结构图 字节码文件 Java虚拟机不和包括Java在内的任何语言绑定,它只与字节码文件这种特定的二进制文件格式所关联. Class文件结构不仅仅是JVM的执行入口,更是Java生态圈的基础和核心. 字节码文件内容是什么 字节码是一种二进制的类文件,他的内容是JVM指令,而不

    2024年02月07日
    浏览(34)
  • 【JavaEE基础学习打卡00】该专栏知识大纲在这里!

    📜 本系列教程适用于 Java Web 初学者、爱好者,小白白。我们的天赋并不高,可贵在努力,坚持不放弃。坚信量最终引发质变,厚积薄发。 🚀 文中白话居多,尽量以小白视角呈现,帮助大家快速入门。 🎅 我是 蜗牛老师 ,之前网名是 Ongoing蜗牛 ,人如其名,干啥都慢,所

    2024年02月10日
    浏览(34)
  • JVM-环境准备&性能指标&基础知识

    环境准备性能指标基础知识 环境准备 JDK — 工具 JDK(Java Development Kit) 是用于开发 Java 应用程序的软件开发工具集合,包括了 Java 运行时的环境(JRE)、解释器(Java)、编译器(javac)、Java 归档(jar)、文档生成器(Javadoc)等工具。简单的说我们要开发 Java 程序,就需要

    2024年02月07日
    浏览(57)
  • JVM,关于JVM基础的知识,你确定不了解一下吗?

    目录 一.JVM的概念 什么是JVM? 二.JVM的运行流程 1.class文件如何被JVM加载并运行 2.JVM运行时数据包括哪些区域(M) 三.类加载的过程(M) 四.双亲委派模型 1.双亲委派模型分析 2.JAVA中有哪些类加载器(M) 五.垃圾回收机制 1.死亡对象的标识 ①引用计数算法 ②可达性分析算法

    2024年02月02日
    浏览(42)
  • Java基础常考知识点(基础、集合、异常、JVM)

    作者: 逍遥Sean 简介:一个主修Java的Web网站游戏服务器后端开发者 主页:https://blog.csdn.net/Ureliable 觉得博主文章不错的话,可以三连支持一下~ 如有需要我的支持,请私信或评论留言! 本文收集Java核心的面试常考知识点,码起面试之前复习!!! JDK(Java SE Development Kit) ,

    2024年02月07日
    浏览(57)
  • jvm中类和对象定义存储基础知识

    Class文件结构主要有两种数据结构: 无符号数和表 • 无符号数 :用来表述数字,索引引用、数量值以及字符串等,比如 图1中类型为u1,u2,u4,u8分别代表1个字节,2个字节,4个字节,8个字节的无符号数 • 表 :表是有由多个无符号数以及其它的表组成的复合结构,比如图1中类

    2024年02月08日
    浏览(54)
  • JAVA后端开发面试基础知识(一)——JVM

    Class loader(类装载) 根据给定的全限定名类名(如: java.lang.Object)来装载class文件到 Runtime data area中的method area。 Execution engine(执行引擎) 执行classes中的指令。 Native Interface(本地接口) 与native libraries交互,是其它编程语言交互的接口。 Runtime data area(运行时数据区域) 这就是我们常说

    2024年03月10日
    浏览(61)
  • C语言初阶测评题:测试你的基础知识和编程技能!!

    💓博客主页:江池俊的博客 ⏩收录专栏:C语言刷题专栏 👉专栏推荐:✅C语言初阶之路 ✅C语言进阶之路 💻代码仓库:江池俊的代码仓库 🎉欢迎大家点赞👍评论📝收藏⭐ 🎈前言: 欢迎来到这个关于C语言的初阶测评题博客!在这里,我们将为您呈现一系列考察基础知识

    2024年02月11日
    浏览(38)
  • 【C语言初阶】带你轻松掌握指针基础知识(1)——指针的定义,类型,大小

    君兮_的个人主页 勤时当勉励 岁月不待人 C/C++ 游戏开发 Hello,这里是君兮_,最近刚回家有点懒,从今天开始恢复更新并开始更新新的刷题系列,我们先继续更新0基础入门C语言的内容,今天给大家带来的是指针方面的内容,但由于是初阶,一些高级的用法我们放在进阶篇再讲

    2024年02月12日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包