共计 4588 个字符,预计需要花费 12 分钟才能阅读完成。
微信公众号【Java 技术江湖】一位阿里 Java 工程师的技术小站。作者黄小斜,专注 Java 相关技术:SSM、SpringBoot、MySQL、分布式、中间件、集群、Linux、网络、多线程,偶尔讲点 Docker、ELK,同时也分享技术干货和学习经验,致力于 Java 全栈开发!(关注公众号后回复”Java“即可领取 Java 基础、进阶、项目和架构师等免费学习资料,更有数据库、分布式、微服务等热门技术学习视频,内容丰富,兼顾原理和实践,另外也将赠送作者原创的 Java 学习指南、Java 程序员面试指南等干货资源)
转自:https://mp.weixin.qq.com/s/Ej…
是大名鼎鼎的 Java 虚拟机,据说这个星球上每天有 900 多万程序员和我打交道,这真是一个惊人的数字。这 900 多万人中不少人对我的技术内幕非常感兴趣,有事儿没事儿都要把我“大卸八块”,深入了解一下。甚至还有人从我的出生地 – 源代码 – 开始看起,弄得人家连一点隐私都没有了。
当然也有很多人对我的运行机理爱理不理,理由很简单:Java 虚拟机相关的事情只有在面试时才会问道,背诵一下那些垃圾回收算法,应付过去就可以了!
真的是这样吗?面试官为什么喜欢问 JVM 原理?难道他们没什么可问的了?或者是只是为了展示他们的卓尔不群?高人一等?压你一头?
我想都不是,请注意一下我的名字:Java 虚拟机,我是一个虚拟机啊!
虽然不是像 VMWare,VirtualBox 那样可以完全虚拟出一个包括内存,硬盘,CPU 的硬件计算机出来,我至少也是个 Soft CPU 啊,有自己的指令集,有自己独有的可执行文件格式,有自己独特的基于栈而不是寄存器的执行方式,还有那久经考验的垃圾回收机制 ……
作为一个口口声声说热爱编程,立志有写出伟大软件来改变世界的程序员,少年,难道你竟然对这么有趣的东西视而不见?
对软件技术的好奇心是你最终成为伟大程序员的第一驱动力,如果你对技术不愿意深究,不愿意了解背后的原理,如果你不愿意像一个调皮捣蛋的熊孩子那样把一个玩具变成零件,然后再组装起来(嗯,实际上永远都组装不起来了),我真的怀疑你在这个行业能呆多久,走多远。
我刚才提到了有趣,那真的有用吗?
表面上看是没有用处的,至少短期看来是没有用处的,你写程序,运行程序,然后吃饭,睡觉。
管你什么基于栈的虚拟机,什么方法区,堆,垃圾回收,生活很美好,世界也很大,我想去看看,不要用这些烦心事来烦我。
如果你想一直生活在软件开发的表层,那肯定是没有问题的,如果你想像 Neo 那样,把这个世界看个清清楚楚,明明白白,真真切切,就需要修炼一下内力,做为 Java 程序员,理解 Java 虚拟机就是那个扎马步的基本功。
举个例子,理解 Class 文件格式,就能理解 ASM 是怎么在运行时“艰难的”动态生成字节码的,然后就会知道 CGLib 是怎么改善它,让它容易使用的。而 CGLib 可是 Spring AOP 赖以生存的一大基础啊。这一路走来,是不是对 AOP 的理解更加透彻了?
你脑海中甚至能想象出来字节码怎么被动态的创建,被 Classloader 加载,形成新的 Class, 然后对你的业务类进行拦截的过程。
看透世界的感觉不要太爽,如果你非要说我会用 Spring 的 AOP 就行了,那我也没办法,人各有志嘛。
扩展一下,现在我的家中上入住了不少动态语言,Jython, JRuby , Clojure , Scala 等等,他们可都需要动态的生成字节码来运行啊(码农翻身备注:Scala 也可以直接编译成 class 文件),你看看理解了 Class 文件格式得有多大的好处。
还有啊,理解了一些重要的字节码指令以后,你就会知道所谓的面向对象,尤其是你写的那些个漂亮的 OO 代码,在我这里已经“退化”成函数调用了,不知道你会不会沮丧,但是没有办法,咱们计算机的本质就是这样,顺序,循环,分支,函数调用。作为补偿,我会让你了解多态的秘密,这可是很多面向对象语言的基础。
说到函数调用,你写的 Java 程序在运行时会形成的 栈帧,这可真是一个超级重要的概念,不仅在我这里有,物理 CPU 和内存在运行本地代码的时候也有,虽然我和他们的结构不同,但都是为了完成一个目的:表达一个函数在运行时的结构。
了解了这个家伙,你就知道函数在机器级是怎么调用的,参数是怎么传递的,递归是怎么回事,尾递归是怎么回事(我竟然不支持!)。也许你会跑去看看汇编,去看看缓冲区溢出攻击,各种知识点开始连接,形成一张大网,这种感觉是极爽的。
这样的例子我还可以举出很多,但是估计很多人已经不耐烦了,就此打住。
你们人类说计算机是门科学,但是科学的成分在哪里呢?在我看来更像一门工程或者技术,核心的基础概念真的不多,花点功夫把他们掌握了,受益终生。
前些天我偷偷地阅读了你们的小说《天龙八部》,里边的扫地僧可真是厉害,轻轻松松就把慕容博和萧远山两位绝顶高手制得服服帖帖,老老实实,这说明的什么问题?内功的修炼真是很重要啊。
jvm.png
前言
JVM(Java Virtual Machine)Java 虚拟机是整个 java 平台的基石,是 java 系统实现硬件无关与操作系统无关的关键部分,是保障用户机器免于恶意代码损害的屏障。Java 开发人员不需要了解 JVM 是如何工作的,** 但是,** 了解 JVM 有助于我们更好的开(通)发(过)java(公司)程(面)序(试)。
写这篇文章的目的:
- 总结所学的 JVM 知识
- 帮助想了解 JVM 的朋友,知无不言,言无不尽
本篇文章将会介绍一下内容:
- 什么是 JVM
- JVM 用来做什么事情
- JVM 生命周期
- JVM 的整体架构
- JVM 内存管理
- 总结
什么是 JVM
要想说明白什么 JVM 就不得不提另外两个概念,JRE 和 JDK,初学者总是把这几个概念搞混
java-tutorial.png
Jvm,Jre,Jdk 都是 java 语言的支柱,他们分工协作。但不同的是 Jdk 和 Jre 是真实存在的,而 Jvm 是一个抽象的概念,并不真实存在。
JDK
JDK(Java Development Kit) 是 Java 语言的软件开发工具包(SDK)。JDK 物理存在,是 programming tools、JRE 和 JVM 的一个集合
jdk.png
JRE
JRE(Java Runtime Environment)Java 运行时环境,JRE 物理存在,主要由 Java API 和 JVM 组成,提供了用于执行 java 应用程序最低要求的环境。
jre.png
JVM
JVM(Java Virtual Machine) 是一种软件实现,执行像物理机程序的机器(即电脑)。
本来,Java 被设计基于从物理机器分离实现 WORA(写一次,随处运行)的虚拟机上运行,虽然这个目标已经几乎被遗忘。
JVM 并不是专为 Java 所实现的运行时,实际上只要有其他编程语言的编译器能生成正确 Java bytecode 文件,则这个语言也能实现在 JVM 上运行。
因此,JVM 通过执行 Java bytecode 可以使 java 代码在不改变的情况下运行在各种硬件之上。
jVM 有如下特点:
- 基于堆栈的虚拟机:最流行的计算机体系结构,如英特尔 X86 架构和 ARM 架构上运行基于寄存器。但是,JVM 是基于栈的。
- 符号引用:除了基本类型以外的数据(类和接口)都是通过符号来引用,而不是通过显式地使用内存地址来引用。
-
垃圾收集:一个类的实例是由用户明确创建的代码和垃圾回收自动销毁。
通过明确界定的基本数据类型的保证平台的独立性:传统的语言,如 C / C ++ 根据平台有不同的 int 型的大小。JVM 中明确规定了基本数据类型,以保持它的兼容性和保证平台的独立性。 - 网络字节顺序:Java class 文件用网络字节码顺序来进行存储:为了保证和小端的 Intel x86 架构以及大端的 RISC 系列的架构保持无关性,JVM 使用用于网络传输的网络字节顺序,也就是大端。
Java bytecode
为了实现 WORA,JVM 使用 Java 字节码,java(用户语言)和机器语言之间的中间语言。
该 Java 字节码是部署 Java 代码的最小单位。
JVM 用来做什么
基于安全方面考虑,JVM 要求在 class 文件中使用许多强制性的语法和机构化约束,但任意一门功能性语言都可以表示为一个能被 JVM 接受的有效的 class 文件。作为一个通用的、机器无关的执行平台,任何其他语言的实现者都可将 JVM 当作他的语言产品交付媒介。
JVM 中执行以下操作:
- 加载代码
- 验证代码
- 执行代码
- 提供运行环境
JVM 提供定义了:
- 存储区
- 类文件格式
- 寄存器组
- 垃圾回收堆
- 致命错误报告等
JVM 生命周期
- 启动:任何一个拥有 main 函数的 class 都可以作为 JVM 实例运行的起点
- 运行:main 函数为起点,程序中的其他线程均有它启动,包括 daemon 守护线程和 non-daemon 普通线程。daemon 是 JVM 自己使用的线程比如 GC 线程,main 方法的初始线程是 non-daemon。
- 消亡:所有线程终止时,JVM 实例结束生命。
JVM 的整体架构
先看一下 java 代码执行过程
关于 Jvm 知识看这一篇就够了
转自:纯洁的微笑 纯洁的微笑 3 月 11 日
2016 年左右的时候读了周志明《深入理解 Java 虚拟机:JVM 高级特性与最佳实践》,读完之后受益匪浅,让我对 Java 虚拟机有了一个完整的认识,这是 Jvm 书籍中最好的读物之一。
后来结合实际工作中遇到的问题,写了一系列关于 Jvm 的文章,其中开篇的几篇内容大部分参考于此书,后期加入自己一些实战的理解,转载了几篇高质量的文章,就形成了此系列读物。
在金三银四的跳槽季中,很多小伙伴们都已经蠢蠢欲动,将此系列文章整理出来,希望可以帮助到大家。
- Jvm 系列(一):java 类的加载机制
第一篇文章讲的是 Java 类的加载机制,也是我在博客园最收欢迎的 Jvm 文章,读完之后你会了解什么是类加载器、类加载机制、双亲委派模型等内容。
- Jvm 系列(二):JVM 内存结构
这篇文章描述了 Java 虚拟机的内存结构,内存每个区域作用,如何通过参数对各个区域进行控制。
- Jvm 系列(三):GC 算法 垃圾收集器
讲述了 Jvm 垃圾回收的经典算法,以及各种垃圾回收机制,对象存活判断等。
- Jvm 系列(四):jvm 调优 - 命令篇
这篇文章讲述了如何通过 Jvm 命令去调优,各 Jvm 命令使用方法。
- Jvm 系列(五):Java GC 分析
这是非常有名的一张图,简单明了展示了 GC 日志的构成
文章介绍如何分析 GC 日志来诊断 Java 项目的运行状态,GC 分析是生产调优的重要手段之一。
- Jvm 系列(六):Java 服务 GC 参数调优案例
一名网友根据 GC 日志,进行 Jvm 调优的经典案例
- Jvm 系列(七):jvm 调优 - 工具篇
介绍了 Jvm 调优各种工具的使用
- Jvm 系列(八):jvm 知识点总览
如何你只是想通过面试,其实只要看一篇就够了,这篇文章将 Jvm 中的关键知识点进行了汇总。
- Jvm 系列(九):如何优化 Java GC
翻译自国外的一篇 Java GC 文章,文章详细描述几种 GC 调优的方式,值得借鉴。
- Jvm 系列(十):教你如何成为 Java 的 OOM Killer
也是线上一场线上 Jvm 实战调优的经历,看着挺爽。
- Jvm 系列(十一):Java 8- 从持久代到 metaspace
Java 8 Jvm 内存变化
- Jvm 系列(十二):Java 8 的新特性—终极版
杜琪翻译的 Java 8 的新特性。
- 一个脚本引发的血案
我们曾经线上出现事故后,定位分析的经历,结局出乎意料。