JVM简介
...
JVM整体结构
- 方法区和堆区是所有线程共享的内存区域;而java栈、本地方法栈和程序员计数器是运行是线程私有的内存区域。
- Java栈又叫做jvm虚拟机栈
- 方法区(永久代)在
jdk8
以后又叫做元空间Metaspace
- 方法区用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器(JIT编译器,英文写作Just-In-Time Compiler)编译后的代码等数据。虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做 Non-Heap(非堆),目的应该是与 Java 堆区分开来。
- 在JDK1.7之前运行时常量池逻辑包含字符串常量池存放在方法区, 此时hotspot虚拟机对方法区的实现为永久代
- 在JDK1.7 字符串常量池被从方法区拿到了堆中, 这里没有提到运行时常量池,也就是说字符串常量池被单独拿到堆,运行时常量池剩下的东西还在方法区, 也就是hotspot中的永久代
- 在JDK1.8之后JVM 已经将运行时常量池从方法区中移了出来,在 Java 堆(Heap)中开辟了一块区域存放运行时常量池。同时在 jdk 1.8中移除整个永久代,取而代之的是一个叫元空间(Metaspace)的区域
- java代码执行流程:
java程序 ->(编译javac)-> 字节码文件.class -> 类装载子系统化身为反射类Class -> 运行时数据区 -> (解释执行)-> 操作系统(Win,Linux,Mac JVM)
提示
运行时环境,和JDK中的 Runtime 类对应。这个类也是单例的。
JVM的生命周期
启动
Java虚拟机的启动是通过引导类加载器(bootstrap class loader)创建一个初始类(initial class)来完成的,这个类是由虚拟机的具体实现指定的。
执行
- 一个运行中的Java虚拟机有着一个清晰的任务:执行Java程序。
- 程序开始执行时他才运行,程序结束时他就停止。
- 执行一个所谓的Java程序的时候,真真正正在执行的是一个叫做Java虚拟机的进程。
退出
有以下几种情况:
- 程序正常执行结束
- 程序异常或错误而异常终止
- 操作系统错误导致终止
- 某线程调用Runtime类或System类的exit方法,或Runtime类的halt方法,并且java安全管理器也允许这次exit或halt操作
- 除此之外,JNI规范描述了用JNI Invocation API来加载或卸载Java虚拟机时,Java虚拟机的退出情况
JVM发展历程
Sun Classic VM
- 第一款商用Java虚拟机,JDK1.4时被淘汰
- 只提供了解释器,效率较差。如果需要JIT编译器(及时编译器),就要进行外挂。但二者不能协同工作
- JIT会把热点代码(执行次数较多的)编译成本地机器指令,并缓存起来。提升了效率
- JIT的缺点:如果把所有代码都编译成本地机器指令,会导致暂停时间太长,导致卡顿
- 现在hotspot内置了此虚拟机
Exact VM
- jdk1.2时由sun提供
- Exact menory management: 准确式内存管理——虚拟机可以知道内存中某个位置的数据具体是什么类型
- 具有热点探测、编译器与解释器混合工作模式
- 只在Solaris平台短暂使用,其他平台上还是classic vm
HotSpot VM
- 1997年由sun收购而来。JDK1.3时,成为默认虚拟机
- Sun/Oracle JDK 和 OpenJDK的默认虚拟机
- 名字中的 hotspot 指的是它的热点代码探测技术
- 通过计数器找到最具编译价值的代码。触发即时编译或栈上替换
- 通过编译器与解释器协同工作,在最优化的程序响应时间与最佳执行性能中取得平衡
BEA 的 JRockit
- 专注于服务器端应用。它可以不太关注程序启动速度,因此JRock内部不包含解析器实现,全部代码都靠即时编译器编译后执行
- JRockit JVM是世界上最快的JVM
- 优势:全面的Java运行时解决方案组合
- 2008年,BEA被Oracle收购。Oracle表达了整合两大优秀虚拟机的工作,大致在JDK8中完成。整合的方式是在 HotSpot 的基础上,移植 JRockit 跹的优秀特性。
IBM 的 J9
- 全称:IBM Technology for Java Virtual Machine,简称 IT4J,内部代号:J9
- 市场定位与 HotSpott 接近,服务器端、桌而应用、嵌入式等多用途 VM
- 广泛用于IBM的各种Java产品。
- 目前,有影响力的三大商用虚拟机之一,也号称是世界上最快的Java虚拟机
你认为这篇文章怎么样?
- 0很棒
- 0不错
- 0一般
- 0???