Java基础篇(JVM)——总领

这篇文章由几个问题组成,目的是想厘清JVM的一些基本概念,同时最后引出JVM知识体系的几大块,以后的文章就围绕这几大块展开。

1. 什么是JVM?它有什么作用?

JVM是Java虚拟机的简写,Java是先编译后解释型的语言,其最初设计的目的是“一次编写,到处运行”,也就是要实现平台的无关性,这个特性正是通过使用JVM实现的。

编译器首先将Java程序编译成字节码.class文件,再由JVM加载,解释成机器指令给不同的系统(从这个意义上说,Java属于解释型语言,因为它并非是直接将代码编译成机器可以理解的二进制文件)。不同系统的JVM是不一样的,但是都能处理.class文件,所以不同运行平台都能处理程序员编写的同一份Java代码。而对于其它传统编程语言来说(如C/C++),由于它和底层密切相关,其基础类型的字节长度是不一样的,导致平台兼容性就差了很多。

2. JVM的特性有哪些?

(1)基于栈的虚拟机:不同于Intel x86和ARM等比较流行的计算机处理器都是基于寄存器[1](register)架构,JVM是基于栈执行的。(通过.class文件反编译(javap -verbose xxx.class)后的字节码文件可以看到,JVM是通过栈将指令逐条压入的)

(2)符号引用:处基本类型以外的所有Java类型都是通过符号引用取得关联的,而非显式的基于内存地址的引用。(类加载机制过程是加载-连接-初始化-使用-卸载,其中,连接分成三步:准备、验证、解析,解析阶段的目的就是将符号引用转变成直接引用)

(3)垃圾回收机制:类的实例由用户显式创建,通过垃圾回收机制进行销毁。

(4)基本类型长度与平台无关。

(5)网络字节序:Java .class文件的二进制表示使用的是基于网络的字节序,即大端(big endian)字节序,保证了各个平台之间的统一性。

(大端字节序:即低位地址存储数据的高位值;小端字节序则相反。

网络字节序是大端字节序,也就是说在网络传输过程中,首先接收到的是数字的高位值。

Intel x86使用小端字节序,RISC[2]系列平台使用了大端字节序)

3. 有哪些类型的JVM?

最主流的是HotSpot VM,是Sun JDK和open JDK共同使用的VM,由于09年Oracle收购了BEA和Sun,在JDK 1.8之后的HotSpot VM是原来的HotSpot VM和JRockit VM的合并版。

HotSpot VM的优点是可以动态编译[3],大大提升了程序执行的性能。

其它的还有:IBM的J9 VM、Zing VM等。

另外,Android平台上的Dalvik,虽然名义上不叫JVM,但它可以将Java代码转化成Dalvik可以使用的代码,其功能基本和JVM相同,也可以归作JVM。(为此,Oracle还告了Google)

4. 字节码是什么?

字节码是程序代码到机器码之间的中间代码。JVM并非一次性将所有字节码读入内存,而是在使用时加载(类加载机制);同时也并非将所有的字节码都预先解释成机器码,而是通过JIT技术,仅解释部分热点代码以提高性能。

可以用JDK自带的反编译命令javap -verbose查看字节码,这时可以看到JVM基于栈的设计,对每个指令都是入栈出栈来执行,另外,还可以看到JVM是符号引用,而非指向直接内存地址的引用;也可以用16进制工具winHex查看字节码,这时会看到魔数、版本号、常量池(个数、类型等)等信息。

5. JDK、JRE和JVM的关系是什么?

JDK包含了JRE,还包含开发工具(编译工具javac、反编译工具javap、打包工具jar等);

JRE是Java程序运行环境,包含了JVM,还包含其它的程序运行需要的系统API,如rt.jar等。

JVM是运行Java程序的核心,用来处理字节码、管理内存等。

6. JVM知识体系分哪几部分?

在我这里,将JVM知识体系分成五个部分:

(1)类的加载机制;

(2)JVM内存模型和内存结构;

(3)GC策略/算法;

(4)GC分析、JVM调优;

(5)虚拟机性能监控与故障处理。

先总述一下这几大块的关系:

对于已有的Java程序代码,首先将其编译成字节码,然后需要加载进内存中,这时要用到类的加载机制(包括类如何加载,什么时候加载,什么时候使用与卸载等);加载进内存中需要分配内存空间,所以要了解JVM的内存模型和内存结构;JVM会针对程序进行GC,所以要了解什么时候GC、如何GC等;接下来还会涉及到JVM调优,调优主要针对的是GC,所以调优之前首先要分析GC的运行情况;最后了解HotSpot虚拟机相关的知识以及虚拟机性能监控和故障处理的知识。

以后JVM的文章大致就围绕这几块展开。

注:

[1] 寄存器:是CPU中的部件,读写速度非常快,可用来进行算术和逻辑运算、存储地址(寻址)等

[2] RISC:即精简指令集的简写。RISC是CPU的一种设计模式,它对指令数目和寻址方式做了精简,且所有指令的格式一致,指令周期相同,使得硬件只用执行简单的那部分指令,其它复杂指令则通过简单指令复合而成。它的实现更容易,并行程度更好,编译效率更高。

[3] 动态编译:也可以叫做JIT。Java是先将程序代码编译成字节码,再由虚拟机解释给不同的机器来执行。使用HotSpot VM,虚拟机可以读入字节码之后,不将所有的字节码都逐条解释成机器码存起来,因为这样效率太低,而是将经常重复执行的“热点”代码先解释成机器码,并进行优化。这样可以提高性能。

原文地址:https://www.cnblogs.com/lilei94/p/9742746.html

时间: 2024-08-03 05:06:20

Java基础篇(JVM)——总领的相关文章

黑马程序员——Java基础篇之对象归要

1.static关键字 1.1.static可以修饰成员变量,成员方法,还有类(其中这里的类是内部类) 1.2.static修饰的部分会随着类的加载而加载: 加载过程:当JVM执行static修饰的代码时,会在内存的共享区给static部分开辟一个空间,供该类持有,static部分不是某个对象的部分,而是该类共有的,所以当一个函数会被多个对象调用时,最好定义成static,这样比较节省空间. 1.3.静态方法只能访问静态成员 原因:如果静态方法中调用了非静态的变量,那么由于静态方法是随着类的加载

Java 基础篇之反射

Java 基础篇之反射 反射# 使用反射获取程序运行时的对象和类的真实信息. 获取 Class 对象# 每个类被加载之后,系统会为该类生成一个对应的 Class 对象,通过该 Class 对象可以访问到 JVM 中的这个类. 使用 Class 类的 forName(String clazzName) 静态方法.字符串参数的值是某个类的全限定类名,必须包含完整的包名 调用某个类的 class 属性 调用某个对象的 getClass() 方法.该方法是 java.lang.Object 类中的一个方

java基础篇---I/O技术(三)

接上一篇java基础篇---I/O技术(二) Java对象的序列化和反序列化 什么叫对象的序列化和反序列化 要想完成对象的输入或输出,还必须依靠对象输出流(ObjectOutputStream)和对象输入流(ObjectInputStream).使用对象输出流输出序列化对象的步骤,有时也成序列化,而使用对象输入流读入对象的过程,有时也称为反序列化 一个对象产生之后实际上是在内存中为其开辟了一个存储空间,方便存储信息. 对象序列化就是把一个对象变成二进制的数据流的一个方法,通过对象序列化可以反驳的

java基础篇IO流的规律

前两篇降了IO流中的字节流和字符流复制的例子,今天来总结一下IO流的规律 掌握好IO流的规律,再开发中会很好用 下面来总结一下: 1,明确源和目的 源:输入流 InputStream 和Reader 目的:输出流 OutputStream 和Writer 2,操作的数据是否是纯文本. 是:使用字符流 不是:使用字节流 3,当体系明确后,在明确要使用哪个具体的对象,通过设备来进行区分 源设备: 内存,硬盘,键盘 目的设备: 内存,硬盘,控制台 这里的源就是你想进行的操作,比如说你想从c盘复制一个文

Java基础篇Socket网络编程中的应用实例

说到java网络通讯章节的内容,刚入门的学员可能会感到比较头疼,应为Socket通信中一定会伴随有IO流的操作,当然对IO流比较熟练的哥们会觉得这是比较好玩的一章,因为一切都在他们的掌握之中,这样操作起来就显得非常得心应手,但是对于IO本来就不是多熟悉的哥们来说就有一定的困难了,在搞清楚IO流操作机制的同时还必须会应用到Socket通信中去,否则会对得到的结果感到非常郁闷和懊恼,下面就和大家一起分享一下自己遇到一点小麻烦后的感触以及给出的解决办法. 要求:客户端通过Socket通信技术上传本地一

面试准备&总结-Java基础篇

在vps的服务器到期了,在hw又不能访问,直接在博客园写笔记了.  基础篇 1. 集合类的继承关系,源码实现原理,初始大小和如何增长. - list类初始大小10,加载因子为1,扩容到1.5+1.底层是个Object数组,调用 System.arraycopy进行拷贝. - Vector同上,扩容倍数是两倍,是同步的,线程安全. - HashMap初始大小16,加载因子0.75f,扩容到2倍.底层是数组+链表,调用resize()调整位置. - HashTable初始大小11,加载因子0.75f

JAVA基础篇NO1--环境变量的配置及命名规则

标签(空格分隔): java基础 一:计算机概述 计算机:硬件和软件 硬件:控制器 运算器 存储器 输入和输出设备       存储器:外存(硬盘) 内存 软件:系统软件 应用软件   系统软件:windows Linux DOS IOS Android Unix macOS           裸机:没有安装操作系统   应用软件:QQ Office MD web APP 二:软件开发与计算机语言 什么是软件?按照特定的组织顺序的数据和指令的集合 计算语言分类 :机器语言(二进制0和1) 汇编

JAVA基础篇八(Java,C++中的网络)

基础篇写到这里,C++和JAVA的基础知识也要讲完了,至于更深入的使用,则需要单独寻找每种语言特有的类库. 讲到网络,不可避免地要讲TCP/IP的基本使用方法.本文只对两种语言的网络实现做简单介绍,后续学习中如果有详细说明,会逐步添加到本文中. 1.C++网络知识 简单的TCP/IP: server端: #include <WINSOCK2.H> #include <stdio.h> #pragma comment(lib,"ws2_32.lib") void

java基础篇---I/O技术(二)

接着上篇http://www.cnblogs.com/oumyye/p/4314412.html java I/O流---内存操作流 ByteArrayInputStream和ByteArrayOutputStream ByteArrayInputStream包含一个内部缓冲区,该缓冲区包含从流中读取的字节,内部计数器跟着read方法要提供的下一个字节.FileInputStream是把文件当做数据源.ByteArrayInputStream则是把内存中的某一个数组单做数据源.ByteArray