加入收藏 | 设为首页 | 会员中心 | 我要投稿 好传媒网 (https://www.haochuanmei.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 资源网站 > 空间 > 正文

想要彻底搞懂Jvm虚拟机,看了这篇就够了

发布时间:2019-08-01 18:08:13 所属栏目:空间 来源:佚名
导读:引言 本文的使用方法: 本文从头读到尾就是一个虚拟机大部分知识点的框架,就像一颗搜索树一样,我们想要了解哪一部分知识,就从根节点开始搜索,直到找到我们想要了解的知识所在的叶节点或者子树。不过如果把所有的知识都在一篇文章中列出来那文章就太长
副标题[/!--empirenews.page--]

 想要彻底搞懂Jvm虚拟机,看了这篇就够了

引言

本文的使用方法:

本文从头读到尾就是一个虚拟机大部分知识点的框架,就像一颗搜索树一样,我们想要了解哪一部分知识,就从根节点开始搜索,直到找到我们想要了解的知识所在的叶节点或者子树。不过如果把所有的知识都在一篇文章中列出来那文章就太长啦,很容易把握不住整体框架,所以本文中对于知识点的详细介绍都以链接的形式给出,大家可以通过本文回忆 JVM 相关的知识,遇到想不起来的点可以点开相应的链接查看,这样像考试一样的学习方式,可以加深我们的印象,记忆效果将远远好于盯着文字硬背。

Content

  • 说说 Java 的内存管理机制
  • 说说 Java 虚拟机程序执行
  • 说说虚拟机性能监控及故障处理
  • 说说 JIT 优化
  • 说说 Java 的内存模型(JMM)
  • 项目推荐

说说 Java 的内存管理机制

和 C++ 相比,Java 的内存管理机制可谓是一大特色,程序员们不需要自己去写代码手动释放内存了,甚至你想自己干虚拟机都不给你干这个事情的机会(就是说,我们是没有办法自动触发 GC 的),虚拟机全权包办了 Java 的内存控制权力。这看起来挺美好的,不过也意味着,一旦虚拟机疏忽了(感觉不能赖虚拟机,毕竟虚拟机也不知道你能把程序写成那样啊……),发生了内存泄漏,问题都不好查,所以知道虚拟机到底是怎么管的内存就十分重要啦。

虚拟机对内存的管理,其实就是收拾哪些存放我们不会再用的对象的内存,把它们清了拿来放新的对象。所以它首先需要研究下以下几个问题:

  • 这堆报废了的对象到底被放哪了?(Java 堆和方法区)
  • 5 个数据区域:程序计数器、Java 虚拟机栈、本地方法栈、Java 堆、方法区。
  • 这堆放报废对象的地方会不会内存泄漏?或者换一个洋气点的叫法,会不会 OOM?(每个区的 OOM)
  • 对象是咋被放到这些地方的?(堆中对象的创建)
  • 对象被安置好了之后虚拟机怎么再次找到它?(堆中对象的访问)

知道对象都放哪了,虚拟机就知道去哪里找报废的对象了,接下来就涉及到了 Java 的一大超级特色:垃圾收集(GC)了,垃圾收集,正如其名,就是把这些报废的对象给清了,腾出来地方放新对象,它主要关心以下几个事情:

  • 哪些内存需要回收?
  • 放对象的地方需要垃圾回收:Java 堆和方法区。
  • 什么时候回收?(判断对象的生死)
  • 判断对象报废了没的算法(重点):引用计数法 和 可达性分析法。
  • 如何回收?
  • GC 算法原理(垃圾收集算法)
  • 基础:标记 - 清除算法
  • 解决效率问题:复制算法
  • 解决空间碎片问题:标记 - 整理算法
  • 进化:分代收集算法
  • GC 算法的真正实现:
  • 7 个葫芦娃,哦不,垃圾收集器
  • 新生代:Serial、ParNew、Parallel Scavenge
  • 老年代:Serial Old、Parallel Old、CMS
  • 全能:G1
  • HotSpot 虚拟机如何高效实现 GC 算法

说完了对象是怎么被回收的,现在才算是把 Java 的内存管理机制需要用到的小零件给补全了。也就是说,Java 的内存管理流程应该是这样滴:

根据新对象是什么对象给对象找个地放

发现内存中没地放这个新对象了就进行 GC 清理出来点地方

真找不着地了就抛 OOM ……

虚拟机一般都用的是进化版的 GC 算法,也就是分代收集算法,也就是说,虚拟机 Java 堆中的内存是分为新生代和老年代的,那么给新对象找地方放的时候放哪呢?具体怎么放呢?放好了之后的对象会不会换个地呆呀?GC 什么时候进行?清理哪呢?……预知 Java 的内存管理机制的详情如何,可以看看我的往期文章。

到此为止,Java 的内存管理机制也就说的差不多了。现在,我们已经知道一个对象是如何在虚拟机的操控下,在内存中走一遭的了。可是首先,对象肯定是根据我们写的类创建的,那么我们写的类到底是如何变为内存中的对象的呢?而且,我们创建对象当然是为了执行它里面的方法呀,那么这个方法是怎么被执行的呢?想要回答这些问题,就需要我们研究一下 Java 虚拟机是如何执行我们的程序的了。

说说 Java 虚拟机程序执行

想要执行 Java 程序,必然要先将 Java 代码编译成字节码文件,也就是 Class 文件,这个编译的过程我们暂且不谈,主要说一下如果执行这个 Class 文件,所以首先我们要先来了解一下 Class 文件的组成结构。

在了解了组成结构之后,接下来需要考虑的事情是,我们该怎么把这个 .class 文件加载进内存,让它变成方法区(Java 8 后变为了 Metaspace 元空间)的一个 Class 对象呢?(类的加载)。

虚拟机的类加载机制说头可就多了,大家都喜欢揪着这问,其实主要就下面这 3 个过程:

  • 类加载的时机:在程序第一次主动引用类的时候。
  • 什么是主动引用和被动引用?
  • 什么是显式加载和隐式加载?
  • 类的生命周期:加载 —— 验证 —— 准备 —— 解析 —— 初始化 —— 使用 —— 卸载
  • 类加载器
  • 如何判断两个类 “相等”?
  • 类加载器的分类?
  • 什么双亲委派模型?
  • 破坏双亲委派模型?
  • 实现 Java 类的热替换
  • 如何自定义类加载器?
  • 需要保留双亲委派模型:extends ClassLoader,重写 findClass()
  • 破坏双亲委派模型:直接重写 loadClass()

将类加载到内存之后,接下来就要考虑如何执行这个类中的方法了。我们知道 5 大内存区域中的 Java 虚拟机栈是服务与 Java 方法的内存模型,那么我们首先应该了解一下 虚拟机栈的栈帧到底是怎样的结构,虚拟机栈的栈帧结构包括如下几个部分:

  • 局部变量表(重要)
  • 操作数栈 & 动态连接 & 方法返回地址

(编辑:好传媒网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读