当前位置: 首页 > news >正文

Java JVM --- JVM内存区域划分,类加载,GC垃圾回收

文章目录

  • JVM
    • JVM内存区域划分
    • 类加载
      • 类加载的基本流程
      • 双亲委派模型
    • GC垃圾回收
      • GC的过程

JVM

  1. JVM主要是面试要考察,它是Java虚拟机中的内容
  2. 面试中经常考的主题:
    (1) JVM 内存区域划分
    (2) JVM 中类加载的过程
    (3) JVM 中垃圾回收机制

JVM内存区域划分

一个运行起来的Java进程就是一个JVM虚拟机,就需要从操作系统申请一大块内存,就会把这个内存,划分成不同的区域,每个区域都有不同的作用。

这个区域就类似租一个写字楼,进行装修
(这个大的场地,相当与申请了一大块内存空间)
在这里插入图片描述
JVM 申请了一大块内存之后,也会划分成不同的内存区域

  1. 方法区(jdk 1.7及其之前)/ 元数据区(jdk 1.8 开始往后)
    这里存储的内容,就是类对象(.class文件,加载到内存之后,就成了类对象了)


  2. 这里存储的内容,就是代码中new的对象
    (占据空间最大的区域)


  3. 这里存储的内容,就是代码执行过程中,方法之间的调用关系

比如 a->b->c->d,a方法调用b方法,b方法调用c方法,以此类推
在这里插入图片描述
4. 程序计数器
比较小的空间,主要就是存放一个地址表示下一条要执行的指令,在内存中的哪个地方(方法区里,每个方法,里面的指令,都是以二进制的形式存在的,保存到对应的类对象中的)
在这里插入图片描述

(1) 刚开始调用方法,程序计数器,记录的就是方法的入口地址。随着一条一条的执行指令,每记录一条,程序计数器的值都会自动更新,去指向下一条指令
(2) 如果是一个顺序执行的代码,下一条指令就是把指令地址进行递增(栈顶是低地址,栈底是高地址)
(3) 如果是 条件/循环代码,下一条指令就可能会跳转到一个比较远的地址
在这里插入图片描述
常见面试题:
给你一个代码,问你某个变量,是处于内存中的哪个区域中?

在这里插入图片描述
有一个问题,容易让我们搞错,变量处于哪个空间上,和变量是不是引用类型,是不是基本类型,没关系~
在这里插入图片描述
每个线程都有自己私有的栈空间
在C++中可以访问别的线程的空间,所以在C++中不是私有的,而在Java中是有自己私有的栈空间的
在这里插入图片描述
5. 内存区域划分
(1) 理解这些区起到的作用
(2) 给你一个代码,给你一个变量,问你这个变量是在哪个区的问题

在这里插入图片描述

类加载

  1. 类加载:java代码会被编译成.class文件(包含了一些字节码),java程序要想运行起来,就需要让jvm读取到这些.class文件,并且把里面的内容,构造成类对象,保存到内存的方法区中。
    jvm就会操作程序计数器去类对象中读取指令,并执行了
    所谓的执行代码,就是调用方法。就需要先知道每个方法,编译后生成的指令都是什么

类加载的基本流程

  1. 书上和官方文档把这个类加载的过程,主要分成了5个步骤(或者是三个步骤,把中间三个步骤合为一个步骤了)
    要想学习这个,最好是去读源码,openjdk是开源的,官方的jdk(oracle)是不开源的

下面的东西都要当做是八股文来背了
(1) 加载:找到 .class 文件,打开文件,读取文件内容
往往代码中,会给定某个类,全限定类名,例如:java.lang.String,java.util.ArrayList,jvm就会根据这个类名,在一些指定的目录范围内,查找

(2)验证:.class文件是一个二进制的格式(某个字节,都有某些特定含义的),就需要验证你当前读到的这个格式是否符合要求
在这里插入图片描述
Attributes:注解
(3)准备:给类对象分配内存空间(最终的目标,是要构造出类对象)
这里只是分配内存空间,还没有初始化呢。此时这个空间上的内存的数值,就是全0的。(此时如果尝试打印类的static成员,就是全0的)

(4)解析:针对类对象中包含的字符串常量进行处理。进行一些初始化操作。java代码中用到的字符串常量,在编译之后,也会进入到.class文件中
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
举个栗子:
期权就是符号引用,股权就是直接引用,公司没有上市就是期权(在文件中),公司上市了就是股权(在内存中)
在这里插入图片描述
5. 初始化:针对类对象进行初始化
把类对象中需要的各个属性都设置好,还需要初始化好static成员,还需要执行静态代码块,以及还可能需要加载一下父类(比如子类继承了父类的)

以上内容,要求我们需要熟练背诵,面试的时候很大概率会遇到原题

双亲委派模型

  1. 双亲委派模型:属于类加载中,第一个步骤(加载中的第一个步骤),其中的一个环节
  2. 作用:负责根据全限定类名,找到 .class文件
    这里的双亲,指的是parent这个单词,双亲之一,parents才是真正的双亲。
    实际上这里翻译成父亲委派模型更合适一些

JVM中内置了三个类加载器:
在这里插入图片描述
3. 类加载的过程(找 .class文件的过程)
在这里插入图片描述
在这里插入图片描述
4. 搞双亲委派模型的主要原因:是为了保证优先级,让标准库优先查找,再让扩展库找,最后让自己写的类和第三方库找
在这里插入图片描述
所谓的双亲委派模型,其实就是一个简单的查找优先级问题,只不过面试中经常考它,是因为它有一个高大上的名字

  1. 双亲委派模型,也不是不可打破的。如果我们自己写一个类加载器,不一定非要遵守上述的流程。

比如:tomcat里,加载webapp的时候就是用的自定义的类加载器。就只能在webapp指定的目录中找,这里找不到,就算了,直接抛异常,不会去标准库啥的里面去找了!!

  1. 可以从最高级的那个加载器开始加载吗?这是可以的,JVM中用了递归的方法,效果都是一样的
    在这里插入图片描述

GC垃圾回收

  1. 在C语言和C++中都有动态申请内存,如果没有及时地释放空间,那么就会产生内存泄漏的风险。
    在这里插入图片描述

  2. 在C++中即使调用了delete,还是有可能出现内存泄漏的问题
    在这里插入图片描述

  3. GC垃圾回收机制的好处:JVM会自动判定这个内存是否要继续使用,如果不用了就会被回收
    在这里插入图片描述

  4. C++为什么不引入GC ?
    在这里插入图片描述
    STW问题就是中间突然卡顿一下

  5. GC真正要释放的是堆上的对象
    在这里插入图片描述

GC的过程

gc可以理解成两个大的步骤:
1.找到垃圾
2.释放垃圾
垃圾:指的是一个不再使用的对象,只是描述了一种客观的状态,没有主观贬低的意思。

如果面试官让你介绍垃圾回收,你可以介绍引用计数。如果让你介绍java的垃圾回收,介绍引用计数就不合适了

  1. 找到垃圾
    在GC的圈子中,有两种主流的方案:
    (1) 引用计数[Python,PHP]
    深入理解java虚拟机中也介绍了引用计数
    引用计数描述这个对象有几个引用指向它,引用计数为0,就是没有对象引用了,就垃圾回收了
    在这里插入图片描述
    为什么Java不使用引用计数?
    引用计数,存在两个重要的问题
    1.比较浪费内存
    在这里插入图片描述
    2.引用计数机制,存在循环引用的问题
    循环引用:存在一个a引用一个对象,一个b引用一个对象,然后a里的的t引用b对象,b里面的t引用a对象,再把a对象和b对象置为null,销毁两引用。那么这两个对象中的t互相引用,要拿到a对象中的t,需要b对象中的t,要拿到b对象中的t,需要a对象中的t。这就是循环引用
    在这里插入图片描述
    (2) 可达性分析[Java]
    可达性分析:本质上是 时间换空间这样的手段。有一个 / 一组线程,周期性的扫描我们的代码中所有的对象。
    在这里插入图片描述
    举个例子:
    二叉树的遍历
    在这里插入图片描述
    可达性分析,出发点有很多,不仅仅是所有的局部变量,还有常量池中引用的对象,还有方法区中的静态引用类型引用的变量…
    这些可以作为出发点的统称为 GCRoots

这里的可达性分析,都是周期性进行的可达性分析比较消耗系统资源,开销比较大,时间上消耗比较大),当前某个对象是否是垃圾,是随着代码的执行,会发生改变(可能当前这个不是垃圾,随着代码的执行,这个就变成了垃圾)

总结:可以到达的点进行全部的遍历,并且是周期性地遍历

  1. 如何回收垃圾
    三种基本的思路
    (1) 标记清除,比较简单粗暴的释放方式(会产生大量的内存碎片,导致后续有足够的空间,但是无法申请)
    在这里插入图片描述

(2) 复制算法(为了解决标记清除)
通过复制的方式,把有效的对象,归类到一起。再统一释放剩下的空间
(先把空间砍一半,比如左边总共有5个对象,但是有2个对象是垃圾,那么要把有效的3个对象复制到右边,然后把左边5个对象都释放掉)
在这里插入图片描述
(3) 标记整理
既能够解决内存碎片问题,又能处理复制算法中利用率的问题
(比如有6个对象,3个对象有效,3个对象是垃圾,把有效的对象都搬运到前面来,后面是垃圾的一起释放掉)
在这里插入图片描述
实际上,JVM采用的释放思路,是上述基础思路的结合体,让不同的方案,扬长避短

在这里插入图片描述
上述结合(JVM释放)的过程:
在这里插入图片描述
分代回收,对象能活过的GC扫描轮次越多,就是越老

新生代,主要使用复制算法进行回收有效的对象,老年代,主要使用标记整理的方式回收有效的对象(标记清除,非常不好用,并没有真正采用)

分代回收,是JVM中主要的回收的思想方法,但是在垃圾回收器的具体实现的时候,可能还有一些调整和优化

其实,分代回收,就和找工作的流程是一样的,都会经历上述的新生代,幸存区和老年代的过程
在这里插入图片描述

主要掌握怎么找垃圾,怎么释放垃圾就可以了

http://www.dtcms.com/a/437903.html

相关文章:

  • 做网站卖广告位赚钱吗最火的自媒体平台排名
  • 从“快递签收规则”看 sigaction:信号处理的“总开关”
  • 中国建设银行官网首页 网站网站顶部flash
  • 微服务项目(k8s集群)部署
  • linux网站建设技术指南 pdf郑州做网站华久科技
  • Conda 常用命令速查表
  • 网站建设如何网络销售html网页教程
  • 大模型面试题剖析:模型微调中冷启动与热启动的概念、阶段与实例解析
  • 计算机网络基础详解:从OSI模型到HTTP/HTTPS与Socket编程
  • 大型网站建设机构小程序订货系统
  • springboot多功能智能手机阅读APP设计与实现(代码+数据库+LW)
  • hadoop-hdfs-journalNode
  • 记一次手机付费充电设备研究
  • 做网站公司价格多少人事外包收费标准
  • 网站百度关键词排名软件网络舆情
  • 网站毕业设计任务书秦皇岛营销式网站制作
  • 注册公司网站源码建设银行企业网站无法打印回单
  • 文化馆的网站怎么建设seo文章外包
  • mvc5 网站开发之美百度沈阳分公司地址在哪里
  • 针对餐饮公司推广做网站方法高端的网站设计多少钱
  • 网站开发不用框架阳春县建设局网站
  • 优秀的网站建设开发案例网站商品管理功能
  • 做网站是什么时候分页贸易网站开发
  • 汕头整站优化wordpress 时区问题
  • 一条龙做网站郑州哪里有做网站
  • 在线制作网站的平台重庆市工程建设招标投标交易信息网
  • 网站基本流程wordpress主题 dux1.8
  • 网站怎么做必须交钱吗贵阳网站建设是什么
  • 深圳罗湖网站建设公司网站关键词排名系统
  • 便宜自适应网站建设厂家贵阳有哪些做网站的公司