JVM 综述
概览
从 JVM 的总体上看,它解决了3个问题:
- Java 程序的内存管理(GC & 运行时数据区)。
- Java Class 二进制字节流的加载(ClassLoader)。
- Java 程序的执行(执行引擎)。
如下图所示:
在我们的日常开发中,最和我们息息相关的就是1和2了,比如 GC 调优,内存故障排查,再比如使用自定义的类加载器去实现一些特定的逻辑,就如我们之前分析的 tomcat 源码中的类加载器用于隔离不同版本的相同类库,必须要使用自定义的类加载器。
1. Java 程序的内存管理(GC & 运行时数据区)
1.1. 运行时数据区
从上图中可以看出,虚拟机内存管理主要由几个部分组成:
- Java 堆(存放对象的地方)
- Java 栈(在 HotSpot 实现中,本地方法栈和虚拟机栈合二为一)
- PC 寄存器(也称为程序计数器)
- 方法区(JDK8 中已经将方法区去除,改为元数据区,解决了方法区----也称为永久代的内存溢出)。
- 直接内存(大小不限制于 Java 堆,直接向操作系统申请,使用场景于读写频繁的场合,例如 NIO)
1.2. 垃圾回收系统
Java 程序员之所以不需要显式的释放内存,一切都归功于 GC,GC 解放了 Java 程序员的双手。GC 系统会在后台清除无用的实例对象,释放内存空间。
而 JVM 中的 GC 可谓是一个庞大的系统,其中分为几个部分:
- 判断什么是垃圾对象
- 垃圾回收算法
- 各种各样的垃圾收集器
我们将会在后面慢慢讲解。
2. Java Class 二进制字节流的加载(ClassLoader)
2.1 类加载器
对于 Java 虚拟机来说,Class 文件是一个重要的接口,无论使用何种语言进行软件开发,只要能将源文件编译为正确的 Class 文件,那么这种语言就可以在 Java 虚拟机上运行。可以说,Class 文件就是虚拟机的基石。
如图所示:
从上图可以看出,虚拟机不拘泥于 Java 语言,任何一个源文件只要能编译成 Class 文件的格式,就可以在JVM 上运行!Class 文件格式就像是一个接口,只要遵守这个接口,就能够在 JVM 上运行。
2.2 类加载器的工作流程
Class 文件通常是以文件的方式存在(任何二进制流都可以是 Class 类型),但只有能被 JVM 加载后才能被使用,才能运行编译后的代码。系统装在 Class 类型可以分为加载,链接和初始化三个步骤。其中,链接也可分为验证,准备和解析3步骤。如图所示:
2.3 类装载的条件
JVM 不会无故装载 Class 文件,只有在必要的时候才装载,哪几个时候呢?
- 当创建一个类的实例是,比如使用 new 关键字,或者通过反射,克隆,反序列化。
- 当调用类的静态方法时,即当使用字节码 invokstatic 指令。
- 当使用类或接口的静态字段时(final 常量除外),比如,使用 getstatic 或者 pustatic 指令。
- 当时用 Java.lang.reflect 包中的方法反射类的方法时。
- 当初始化子类,要求先初始化父类。
- 作为启动虚拟机,含有 main()方法的那个类。
以上6种情况属于主动调用,主动调用会触发初始化,还有一种情况是被动调用,则不会引起初始化。
2.4 类加载器的双亲委派模型
先来看一个著名的图:
虚拟机为了保护应用程序内出现多个类名相同的类对象,因此发明了这个机制:当 JVM 需要适用一个类时,在判断类是否已经被加载时,会先从当前底层类加载器进行判断。当系统需要加载一个类时,会从顶层类开始加载,依次向下尝试,知道成功,否则抛出ClassNotFound 异常。
# 总结
这篇文章主要是为了后面的详细文章做一个大纲,因此只是讲述以 JVM 的一些基本的框架和概念,后面讲详细的讲述内部细节。让我们学习虚拟机更加的有条理。
JVM 综述的更多相关文章
- 深入浅出 JVM ClassLoader
# 前言 在 JVM 综述里面,我们说,JVM 做了三件事情,Java 程序的内存管理, Java Class 二进制字节流的加载(ClassLoader),Java 程序的执行(执行引擎).我们也说 ...
- 【转】Java学习---垃圾回收算法与 JVM 垃圾回收器综述
[原文]https://www.toutiao.com/i6593931841462338062/ 垃圾回收算法与 JVM 垃圾回收器综述 我们常说的垃圾回收算法可以分为两部分:对象的查找算法与真正的 ...
- 垃圾回收算法与 JVM 垃圾回收器综述(转)
垃圾回收算法与 JVM 垃圾回收器综述 我们常说的垃圾回收算法可以分为两部分:对象的查找算法与真正的回收方法.不同回收器的实现细节各有不同,但总的来说基本所有的回收器都会关注如下两个方面:找出所有的存 ...
- 性能分析之-- JAVA Thread Dump 分析综述
性能分析之-- JAVA Thread Dump 分析综述 一.Thread Dump介绍 1.1什么是Thread Dump? Thread Dump是非常有用的诊断Java应用问题的工 ...
- 监控服务器JVM内存运行
使用jdk的jconsole进行监控jmx 首先,设置监控对象的端口 配置 catalina.sh #vi /usr/tomcat/bin/catalina.sh 注: /usr/tomcat/b ...
- JAVA技术专题综述之线程篇(1)
本文详细介绍JAVA技术专题综述之线程篇 编写具有多线程能力的程序经常会用到的方法有: run(),start(),wait(),notify(),notifyAll(),sleep(),yield( ...
- 面试为什么需要了解JVM
匠心零度 转载请注明原创出处,谢谢! 说在前面 如果你经常注意面试题,你会发现现在面试题多多少少会含有jvm相关的面试题,之前也把一些jvm面试题汇总了下:面试题系列一,那么为什么现在面试需要了解或者 ...
- JVM内存管理概述与android内存泄露分析
一.内存划分 将内存划分为六大部分,分别是PC寄存器.JAVA虚拟机栈.JAVA堆.方法区.运行时常量池以及本地方法栈. 1.PC寄存器(线程独有):全称是程序计数寄存器,它记载着每一个线程当前运行的 ...
- JVM:类的生命周期
类的生命周期 综述 1. 只有当一个类被切实使用到的时候才会被加载到虚拟机中(例如:new, 方法调用, A a = null;不算) 2. 若在加载一个类的过程中,有其他类被切实使用到, ...
随机推荐
- [Chrome_Error] (failed) net::ERR_INCOMPLETE_CHUNKED_ENCODING 与 nginx 502 bad gateway
Chrome 浏览器出现这个错误,还出现 nginx 502 bad gateway . 查看 nginx 的 error.log : 2015/12/18 14:34:44 [error] 1448 ...
- WPF 右上角带数字的按钮
效果如图所示 三种方案, 1:不改控件模版,布局实现,死开 2:改button模版,利用附加属性,附加附加属性,功能多了话,不利于拓展 3:继承button,添加依赖属性,接下来是这种 1:新建类 为 ...
- 改变PowerDesigner数据模型字体大小
一 改变左侧菜单字体大小Tools----->General------->Fonts-------->根据item选项的不同改变字体的大小 二 改变数据模型Table的字体大小To ...
- 【转】JS浮点数运算Bug的解决办法
37.5*5.5=206.08 (JS算出来是这样的一个结果,我四舍五入取两位小数) 我先怀疑是四舍五入的问题,就直接用JS算了一个结果为:206.08499999999998 怎么会这样,两个只有一 ...
- 有标号的DAG图计数1~4
前言 我什么都不会,菜的被关了起来. 有标号的DAG图I Solution 考虑递推,设\(f_i\)表示i个点的答案,显然这个东西是可以组合数+容斥递推? 设\(f_i\)表示i个点的答案,我们考虑 ...
- MariaDB 视图与触发器(11)
MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可MariaDB的目的是完全兼容MySQL,包括API和命令行,MySQL由于现在闭源了,而能轻松成为MySQ ...
- [学习笔记]CDQ分治和整体二分
序言 \(CDQ\) 分治和整体二分都是基于分治的思想,把复杂的问题拆分成许多可以简单求的解子问题.但是这两种算法必须离线处理,不能解决一些强制在线的题目.不过如果题目允许离线的话,这两种算法能把在线 ...
- 反向读取Mysql数据库表结构到PowerDesigner中
使用PowerDesigner挺长时间了,只是一些简单的表结构设计,因需要对当前数据库进行再设计,需要看一下数据库中所有的表,及表之间的关系,并重新修改表结构,因此需求就是怎么把数据库中的表结构反向生 ...
- Redis 入门知识
Redis 的前世今生 Redis的诞生于2008年,由Salvatore Sanfilippo开发.最初作者在开发一个网站时,需要实现一个高性能的队列功能,在使用Mysql无果后,决定自己造一个轮子 ...
- C# 单元测试(入门)
注:本文示例环境 VS2017XUnit 2.2.0 单元测试框架xunit.runner.visualstudio 2.2.0 测试运行工具Moq 4.7.10 模拟框架 什么是单元测试? 确保软件 ...