java虚拟机被称为“虚拟”,因为它是一个抽象的计算机定义的规范。要运行一个Java程序,需要一个抽象的规范的具体实现。以下内容主要还是参考《Inside JVM》

什么是JVM?

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM三种不一样的地方:抽象的规范,一个具体的实现,运行时的实例。

JVM的生命周期

java虚拟机种运行的一个实例有着明确的“使命”:运行一个java程序,当程序启动时,产生一个运行实例,当程序运行完成时,实例就没了。如果同时启动三个java程序,在同一台电脑上,使用相同的实现方法,你就会得到三个java虚拟机的实例,每个java程序运行在自己的虚拟机实例上面。

Java虚拟机实例通过调用一些初始类的main()方法来开始运行其单独应用程序,该main()方法必须时公共(public),静态(static),无返回值的(void),并且接受一个字符串数组的参数(String[] args),按照上面定义的main()方法,任何一个类的main方法都可以作为程序启动的起点。


public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

在java虚拟机中,线程分两种:守护线程(daemon,也可以成为后台线程)和 非守护线程(non-daemon,前台线程)。


daemon守护线程是JVM自己用的,就比如我们常说的垃圾回收。non-daemon非守护线程,应用程序启动了main(),然后再调用我们自己写的方法。 一个java程序在运行时,只要非守护线程一直运行,那么java虚拟机实例就一直存在,当所有的java非守护线程中断时,java虚拟机实例也就消失了。当然我们也可以直接通过类Runtime或者类System调用exit()方法来使程序中断。

JVM的体系结构

在java虚拟机规范中,java虚拟机的行为是由子系统,内存区域,数据类型和指令来描述的。这些组件的目的与其说是决定内部架构的实现,更提供了一种严格定义的外部行为的实现。规范定义了所需的任何Java虚拟机的行为来实现这些抽象组件及其之间的交互。

一个Java虚拟机,包括主要的子系统和内存区域中描述的规范如前一章中提到,每个Java虚拟机有一个类装入器子系统:加载机制类型(类和接口)指定完全限定的名称。每个Java虚拟机还提供一个执行引擎:一种机制负责执行的指令包含在加载的类的方法。

当一个Java虚拟机运行一个程序的时候,他需要内存存储更多的东西,包括直接码和其它信息摘录加载类文件,程序实例化对象,参数方法,返回值,局部变量,计算的中间结果。虽然相同的数据区域运行在每一个java虚拟机的实现上,规范是抽象的,但具体运行这些数据区域的细节的时候还是需要(设计者)实现者来具体实现。

不同的java虚拟机的实现有很多不同的内存限制,有些实现需要很多的内存为其工作,而有的实现却需要的很少;有的实现可以利用java虚拟内存,有的却不可以;运行时数据区域的抽象性质规范更容易在各种各样的电脑和设备实现Java虚拟机。

一些运行时的数据区被一个程序线程或者其它独一无二的线程所共享,每一个java虚拟机实例都有一个方法区(method area)和堆(heap)。这些区域内运行的所有线程共享虚拟机。当JVM加载一个类文件(class文件)时,JVM会从二进制数据中解析出包含信息类型的类文件。它会把这些类的文件送到方法区里面去。当程序运行时,虚拟机将所有对象实例化到堆(heap)。

因为每个新线程启动,它有自己的电脑注册(程序计数器)和Java堆栈。如果线程正在执行Java方法(不是一个本地方法),pc寄存器的值显示为要执行下一个指令。Java堆中存储着Java线程(非原生)方法调用的状态。Java方法调用的状态包括局部变量、被调用的参数,它的返回值(如果有的话),中间的计算。本地方法调用的状态以具体实现相关的方式在本地方法栈存储着,以及可能在寄存器或其他具体实现相关的内存区域。Java堆栈由堆栈帧(帧)组成。一个堆栈帧包含一个Java方法调用的状态,说白了就是每个栈就是一个每个调用的方法。当一个线程调用一个方法时,Java虚拟机会分配一个新的栈给那个线程的方法。当方法完成时,虚拟机就会丢弃此方法的栈。Java虚拟机没有寄存器来保存中间数据值。指令集被使用在Java堆栈存储这些中间数据值。

上图中,线程1和2是执行java方法,线程3 执行本地的方法。

JVM的数据类型

Java虚拟机通过操作某些类型的数据来进行计算。这些数据类型和操作都严格定义的Java虚拟机规范。可以分为一组基本类型和引用类型。变量的原始类型保存原始值,变量的引用类型值的引用。引用值引用对象,但不是对象本身。原始值,相比之下,不参考任何东西。他们是实际数据本身。

所有原始类型的Java编程语言,除了布尔类型,其它都是是Java虚拟机的基本类型。编译器将Java源代码转换为字节码时,它使用int或字节来表示布尔值。在Java虚拟机中,错误的是由整数0和真正的任何非零的整数,业务涉及到布尔值使用int。布尔访问数组作为字节数组,尽管它们可能在堆上表示为字节数组或字段。原始类型的Java编程语言以外的布尔形成了数字类型的Java虚拟机。之间的数值类型为: byte, short, int, long, , char。与Java编程语言一样,Java虚拟机的基本类型有相同的范围。长在Java虚拟机总是像一个64位表示整数,独立于底层主机平台。Java程序员可以使用适用于Java虚拟机而不在原始类型中的returnValue类型。这种原始的类型在Java程序被使用。引用类型分为三种:类类型,接口类型和数组类型。所有三种类型值对动态创建对象的引用。class type值对类实例的引用。array type值是数组的引用,这是成熟的对象在Java虚拟机。interface type值是实现一个接口的类实例的引用。另一个值是null值的引用,这表明没有引用任何对象的引用变量。Java虚拟机规范定义了每个数据类型的值的范围,但没有定义他们的大小。bits比特数用来存储每个数据类型。

下篇将详细介绍JVM中heap,stack,method area如何工作的

JVM知识(上)的更多相关文章

  1. JVM 平台上的各种语言的开发指南

    JVM 平台上的各种语言的开发指南 为什么我们需要如此多的JVM语言? 在2013年你可以有50中JVM语言的选择来用于你的下一个项目.尽管你可以说出一大打的名字,你会准备为你的下一个项目选择一种新的 ...

  2. [转帖]【JVM 知识体系框架总结】

    [JVM 知识体系框架总结] https://www.cnblogs.com/mousycoder/p/11612448.html JVM 内存分布 线程共享数据区:方法区->类信息,静态变量堆 ...

  3. 深入理解java虚拟机JVM(上)

    深入理解java虚拟机JVM(上) 链接:https://pan.baidu.com/s/1c6pZjLeMQqc9t-OXvUM66w 提取码:uwak 复制这段内容后打开百度网盘手机App,操作更 ...

  4. JVM 线上故障排查

    JVM 线上故障排查 Linux 1.1 CPU 1.2 内存 1.3 存储 1.4 网络 一.CPU 飚高 寻找原因 二.内存问题排查 三.一般排查问题的方法 四.应用场景举例 4.1 怎么查看某个 ...

  5. 自动化预备知识上&&下--Android自动化测试学习历程

    章节:自动化基础篇——自动化预备知识上&&下 主要讲解内容及笔记: 一.需要具备的能力: 测试一年,编程一年,熟悉并掌握业界自动化测试工具(monkey--压力测试.monkeyrun ...

  6. JVM史上最全实践优化没有之一

    JVM史上最全优化没有之一 1.jvm的运行参数 1.1 三种参数类型 1.1.1 -server与-clinet参数 2.1 -X参数 2.1.1 -Xint.-Xcomp.-Xmixed 3.1 ...

  7. JVM 线上故障排查基本操作--CPU飙高

    JVM 线上故障排查基本操作 CPU 飚高 线上 CPU 飚高问题大家应该都遇到过,那么如何定位问题呢? 思路:首先找到 CPU 飚高的那个 Java 进程,因为你的服务器会有多个 JVM 进程.然后 ...

  8. JVM知识(一) 求你了,别再说Java对象都是在堆内存上分配空间的了!

    求你了,别再说Java对象都是在堆内存上分配空间的了! https://baijiahao.baidu.com/s?id=1661296872935371634&wfr=spider& ...

  9. JVM 线上故障排查基本操作

    # 前言 对于后端程序员,特别是 Java 程序员来讲,排查线上问题是不可避免的.各种 CPU 飚高,内存溢出,频繁 GC 等等,这些都是令人头疼的问题.楼主同样也遇到过这些问题,那么,遇到这些问题该 ...

随机推荐

  1. 3.2 Spark内置RPC框架

    实现的HttpFileServer,但在Spark 2.0.0版本中它也被废弃了,现在使用的是基于Spark内置RPC框架的NettyStreamManager.节点间的Shuffle过程和Block ...

  2. PHP面试系列 之框架(一)---- MVC框架基本工作原理

    题:谈谈你对MVC的认识,介绍集中目前比较流行的MVC框架 考点: (1)MVC工作原理 (2)常见MVC框架 延伸: (1)单一入口的工作原理 (2)模板引擎的理解 (1)MVC工作原理 Model ...

  3. Shell笔记-01

    打开文本编辑器,新建一个文件,扩展名为sh(sh代表shell),扩展名并不影响脚本执行,见名知意就好,如果你用php写shell 脚本,扩展名就用php好了. 输入一些代码: #!/bin/bash ...

  4. CodeForces - 999D Equalize the Remainders (模拟+set)

    You are given an array consisting of nn integers a1,a2,…,ana1,a2,…,an , and a positive integer mm . ...

  5. What to do next to activate this settings for already existing users

    Link: http://sharepoint.stackexchange.com/questions/89284/sharepoint-2013-mysite-increase-quota Cent ...

  6. Extjs6 组件浅谈

    一.Component组件 一个 Ext JS 应用的界面由一个或多个叫做 组件的控件组成. 所有的组件都是 Ext.Component 类的子类,这个类可以允许参与包含实例化.渲染.自动大小和位置以 ...

  7. functional filter()

    #include "pch.h" #include <iostream> #include <deque> #include <string> ...

  8. c# Reverse()的两点用法

    Rervese的基本用途是:反转数组中元素的顺序,常见的两种用法如下: 1.void Array.Reverse(Array array) static void Main(string[] args ...

  9. linux 学习第十五天(vsftpd配置)

    一.vstapd配置 vsftpd 服务(a.匿名公开 b.系统本地账户验证c.虚拟专用用户验证) iptables -F  (清空防火墙) service iptables save  (保存防火墙 ...

  10. 搭建iSCSI共享IPSAN

    iSCSI(internet SCSI)是一个供硬件设备使用的.可以在IP协议的上层运行的SCSI指令集,这种指令集合可以实现在IP网络上运行SCSI协议,使其能够在诸如高速千兆以太网上进行路由选择. ...