【JVM】概述
前言
Java的技术体系主要由支撑Java程序运行的虚拟机、提供各开发领域接口支持的Java类库、Java编程语言及许许多多的第三方Java框架(如Spring、MyBatis等)构成。在国内,有关Java类库API、Java语言语法及第三方框架的技术资料和书籍非常丰富,相比而言,有关Java虚拟机的资料却显得异常贫乏。这种状况很大程度上是由Java开发技术本身的一个重要优点导致的:在虚拟机层面隐藏了底层技术的复杂性以及机器与操作系统的差异性。运行程序的物理机千差万别,而Java虚拟机则在千差万别的物理机上面建立了统一的运行平台,实现了在任意一台Java虚拟机上编译的程序,都能在任何其他Java虚拟机上正常运行。这一极大的优势使得Java应用的开发比传统C/C++应用的开发更高效快捷,程序员可以把主要精力放在具体业务逻辑,而不是放在保障物理硬件的兼容性上。通常情况下,一个程序员只要了解了必要的Java类库API、Java语法,学习适当的第三方开发框架,就已经基本满足日常开发的需要了。虚拟机会在用户不知不觉中完成对硬件平台的兼容及对内存等资源的管理工作。因此,了解虚拟机的运作并不是普通开发人员必备的,或者说首要学习的知识。
然而,凡事都具备两面性。随着Java技术的不断发展,它已被应用于越来越多的领域之中。其中一些领域,如互联网、能源、金融、通信等,对程序的性能、稳定性和扩展性方面会有极高的要求。一段程序很可能在10个人同时使用时完全正常,但是在10000个人同时使用时就会缓慢、死锁甚至崩溃。毫无疑问,要满足10000个人同时使用,需要更高性能的物理硬件,但是在绝大多数情况下,提升硬件性能无法等比例提升程序的运行性能和并发能力,甚至有可能对程序运行状况没有任何改善。这里面有Java虚拟机的原因:为了达到“所有硬件提供一致的虚拟平台”的目的,牺牲了一些硬件相关的性能特性。更重要的是人为原因:如果开发人员不了解虚拟机诸多技术特性的运行原理,就无法写出最适合虚拟机运行和自优化的代码。
其实,目前商用的高性能Java虚拟机都提供了相当多的优化参数和调节手段,用于满足应用程序在实际生产环境中对性能和稳定性的要求。如果只是为了入门学习,让程序在自己的机器上正常工作,那么这些特性可以说是可有可无的;但是,如果用于生产开发,尤其是大规模的、企业级的生产开发,就迫切需要开发人员中至少有一部分人对虚拟机的特性及调节方法具有很清晰的认识。所以在Java开发体系中,对架构师、系统调优师、高级程序员等角色的需求一直都非常大。学习虚拟机中各种自动运作特性的原理也成为Java程序员成长路上最终必然会接触到的一课。
为什么要学习JVM?
面试的需要
作为应届大学生,学习Java时长两年半,对JVM并不陌生。其实不懂JVM也照样能写出优质的代码,但是去面试大厂,不懂JVM的同学很有可能被面试官虐得体无完肤。
中高级程序员必备技能
项目管理、性能调优。如果想要一个长远的发展,比如先定一个小目标:三年做到组长(管理开发人员,以技术为主),五年做到项目主管(不写代码,统筹管理整个项目,负责产品的开发、测试、运维、客户对接等)或者技术总监(超脱业务,只管技术架构)。JVM这一块肯定是要深入理解的。
JVM的作用
先纠正一个大多数人的误区:把.java文件编译成.class文件,不是 JVM 干的事情,而是 javac干的事情,JVM 起步就是加载.class文件。.java — javac —> .class 这个编译是在开发阶段就进行的。
JVM 负责将字节码文件加载到虚拟机中,再将字节码文件解释/编译为机器码。编译完成后管理运行时数据的存储、垃圾回收等······
现在的 JVM 还可以执行其他语言编译后的字节码文件:
JVM的构成
类加载器(ClassLoader)
负责从硬盘上加载字节码文件到 JVM 中。
运行时数据区(Runtime Data Area)
按照不同的数据分区进行存储(方法区、堆、栈、本地方法栈、程序计数器)。
执行引擎(Execution Engine)
将字节码再次编译/解释为机器码。
本地库接口(Native Interface)
负责调用本地操作系统方法。
先对其整体组成有一个宏观的认识: