`

JVM之(一)概述

    博客分类:
  • JVM
 
阅读更多

来自:http://www.haogongju.net/art/1223673

一、JVM的概念

通常我们所提到的“JVM”有着多重的意义,一般来讲,JVM既可以用来描述一个“抽象规范”,也可以用来描述一个规范的具体实现,同时还可以用来一个运行中的虚拟机实例。而JVM具体指这些含义中的哪一个,要根据该词所处的上下文环境来进行分析

二、JVM的生存周期

一个JVM的作用就是用来负责运行一个Java程序,当该程序启动时,一个JVM实例也就产生了,当该程序运行完毕退出时,该JVM实例也就随之消亡了。

只要有任何非守护线程[1]在运行,Java程序也就在继续运行,JVM也就在存活状态之中。当程序中所有的非守护线程都终止时,JVM实例将退出。

三、JVM的数据类型

四、JVM系统结构

 

4.1 类装载子系统

4.1.1类装载器子系统的作用

类装载子系统是JVM中负责查找并装载类型的子系统。

JVM对于每个被装载的类型,都会创建一个java.lang.Class类实例来代表该类型。

类装载子系统除了要定位和导入二进制class文件时外,还必须负责验证被导入类的正确性为类变量分配并初始化内存,以及帮助解析符号引用

4.1.2类装载器的分类

JVM中包含两种类装载器:启动类装载器和用户定义的类装载器。前者是JVM实现的一部分,而后者则是使用Java语言实现,是Java程序的一部分。

4.1.2.1 启动类装载器

每个JVM都必须有一个启动类装载器,它知道如何去装载受信任的类(如Java类库等)。

4.1.2.2 用户自定义的类装载器

用户自定义的类载器必须派生自java.lang.ClassLoader类,主要通过以下几个方法来处理类装载:

(1)protected final Class<?> defineClass(String name, byte[] b, int off, int len)

(2)protected final Class<?> defineClass(String name, byte[] b, int off, int len,

                   ProtectionDomain protectionDomain)

方法(1)和方法(2)负责定义一个新的类型。

(3)protected final Class<?> findSystemClass(String name)

    throws ClassNotFoundException

(4)protected final void resolveClass(Class<?> c)

方法(3)根据类的全限定名来使用系统类装载器来装载该类型。

方法(4)对类型的Class实例来执行连接动作。

4.1.3命名空间

在JVM中,每个类装载器都有自己的命名空间,在该空间内维护着由其负责装载的类型。命名空间其实是一种解析过程的结果。对于每一个被装载的类型,JVM都会记录装载它的类装载器,当JVM解析到一个类到另外一个类的符号引用时,它需要被引用类的类装载器。

类装载器名称+类型的全限定名构成了类型的唯一标识。

4.2 方法区

方法区是所有线程共享的,因此方法区数据的访问必须实现为线程安全的。方法区只是一个逻辑上的概念,它并不要求实际上其大小必须是固定的,也不必是连续的内存。方法区可以在一个堆(甚至是虚拟机自己的堆)中自由分配,也可以允许用户或者程序员来指定方法区的初始大小及最大最小尺寸等。

方法区是可以被垃圾回收器回收的。

4.2.1方法区的作用

在JVM中,被装载的类型信息存储在一个逻辑上称作“方法区”的内存中。当虚拟机装载某个类型时,它使用类装载器定位相应的class文件,然后读入这个class文件(二进制线性数据流),然后将其传输到JVM中,然后JVM提取出其中的类型信息,并将这些信息存储到方法区。该类型中的类变量也是存储在方法区的。

4.2.2方法区存储的具体信息

l         类的全限定名

l         类的直接超类的全限定名(java.lang.Object不需要)

l         类类型还是接口类型

l         类型的访问修改

l         直接超接口的全限定名的有序列表

l         常量池[2]

l         字段信息

  • 字段的声明顺序
  • 字段名
  • 字段类型
  • 修饰符

l         方法信息

  • 方法声明的顺序
  • 方法名
  • 方法的返回类型
  • 方法参数的数量和类型(按声明顺序)
  • 方法的修饰符
  • 方法的字节码、操作数栈和局部变量区的大小、异常表(非abstract和native的方法)

l         除常量外的所有类变量

l         一个到类ClassLoader的引用

l         一个到Class类的引用

4.3 堆

Java程序在运行时创建的所有类实例或数组都存储在同一个堆中。一个Java虚拟机实例中只存在一个堆空间,所有线程都共享这个堆空间,因此,堆空间数据的访问也是要求要线程安全的。

堆空间也不要求是连续的内存空间,它可以动态扩展。

4.3.1数组的内部实现

在Java中,数组是真正的对象。数组总是存储在堆中。同其它所有对象一样,数组也拥有一个与它们的类相关联的Class实例,所有具有相同维度和类型的数组都是同一个类的实例,而不管数组的长度(多维数组每一维的长度)是多少。

数组类的名称由两部分组成,每一维用一个方括号“[”表示,用字符或字符串表示元素类型。如[I,[[Ljava/lang/Object。

4.4 Java栈

当启动一个线程时,JVM都会为它分配一个Java栈。JVM只对会Java栈进行两种操作:压栈和出栈。当线程调用一个方法时,JVM都会在该线程的Java栈中压入一个新帧。

Java栈上的所有数据都是线程私有的。任何一个线程都不能访问另一个线程上的栈数据。

Java栈和帧在内存中也不必是连续的。

4.4.1桢帧

栈帧由在三部分组成:局部变量区、操作数栈和帧数据区。局部变量区和操作数栈的大小在编译时就会计算完毕,存储在class文件中。帧数据区的大小要视具体的实现而定。

当虚拟机调用一个Java方法时,它从对应的类信息中得到此方法的局部变量区和操作数栈的大不,并据此分配内存,然后压入到Java栈中。

4.4.1.1 局部变量区

局部变量区是以一个以字长为单位,从0开始计算的数组。字节码指令通过从0开始的索引来使用其中的数据。类型为int, float, reference和returnAddress的值在数组中占一项,而类型为byte, short和char的值在存储数组之前都会强制转换为int类型,也占一项。类型为long和double类型的值在数组中占据连续的两项。

局部变量区包含对应方法的参数和变量,编译器首先按照声明的顺序将其放到局部变量数组。

4.4.1.2 操作数栈

操作数栈与局部变量区一样,也是被组织成一个以字长为单位的数组,但其并不通过索引来访问,而是通过标准的栈操作:压栈和出栈来访问的。

4.4.1.3 帧数据区

除了局部变量区和操作数栈外,Java栈帧还需要一些数据来支持常量池解析、正常方法返回和异常派发机制。这些信息都保存在帧数据区中。

4.5 程序计数器

对于每一个运行中的Java程序而言,其中的每一个线程都有属于自己的PC(程序计数器)寄存器,在线程创建时创建PC。PC寄存器的大小是一个字长。在线程执行Java方法时,PC寄存器的内容总是指向下一条将被执行指令的“地址”,这里的“地址”可以是一个本地指针,也可以是在方法字节码中相对于该方法起始指令的“偏移量”。如果该线程正在执行的是本地方法,PC寄存器中的值是“undefined”。

4.6 本地方法栈

任何本地方法接口都会使用某种本地方法栈。当线程调用Java方法时,虚拟机会创建一个新的栈帧并压入到Java栈。当其调用到本地方法时,虚拟机会保护Java栈不变,不再在线程的Java栈中压入新的栈帧,虚拟机只是简单地动态连接并直接调用指定的本地方法。这可以看作是虚拟机利用本地方法来动态地扩展自己。

如果某个虚拟机实现的本地方法接口是使用C连接模型的话,那么它的本地方法栈就是C栈。

本地方法栈占用的内存区也不必是固定大小的,它可以根据需要动态扩展或收缩。某些实现也允许用户或者程序员指定该内存区的初始大小及最大、最小值。

4.7 执行引擎

JVM的核心是其执行引擎部分。在JVM规范中,执行引擎的行为使用指令集来进行定义。对于每条指令,规范都详细规定了当实现执行到该指令时应该处理什么,但对实现细节没有约束。

4.7.1指令集

方法的字节码流都是由Java虚拟机的指令序列构成的。每一条指令包含一个单字节的操作码,后面跟随0个或多个操作数。操作码表明需要进行的操作;操作数向操作码提供执行时所需要的额外信息。

4.7.2执行技术

实现可以采用多种执行技术:解释、即时编译、自适应优化芯片级直接执行等,只要符合JVM规范中对指令规定的操作即可。

 



[1] 守护线程,通常是由虚拟机自己使用的线程。但Java语言允许将其创建的线程设置为守护线程。Java程序初始运行的初始线程,即main方法所处的线程,是非守护线程。

[2] 常量池是该类型所用常量的一个有序集合,包括直接常量(string, integer和float point常量)和对其它类型、字段、方法的符号引用。其中的数组项访问就像数组一样是通过索引来访问的。

分享到:
评论

相关推荐

    java垃圾回收以及jvm参数调优概述

    Java技术体系中所提倡的自动内存管理最终可以归结为自动化地解决了两个问题:给对象分配内存以及回收分配给对象...本文主要对java垃圾回收机制以及jvm参数等方面做个综述,也算是自己做开发这几年对这方面的一个总结。

    JVM详细概述与优化大全.rar

    JVM详细概述与优化大全 从JVM基础知识点出发,再到JVM性能优化,全面详述JVM的实用场景以及优化实践,非常值得收藏

    JVM历史发展和内存回收笔记

    JVM历史发展和内存回收笔记

    JVM详细概述与优化大全.zip

    JVM详细概述与优化大全.zip

    JVM详细概述与优化大全

    JVM详解与优化

    涨见识!JVM性能监控与调优实战 一线大厂大牛讲师的JVM优化案例与解决方案课程

    JVM性能监控与调优实战课程,作为整篇课程的重中之重,非常值得同学们参考学习。课程前端讲解了JVM的性能监控和调优的概述,对调优的的方法和工具进行讲解学习,让同学们掌握方法,理解知识。课程的中间阶段我们进行...

    jvm 内存分析文档

    1.jvm内存结构及功能概述 2.Jvm Heap 内存结构 3.Jvm 的内存分配

    JVM笔记.docx

    目录: 1.JVM体系结构概述 2.堆体系结构概述 3.堆参数调优入门 4.总结

    jvm原理及调优

    一、JVM概述 二、JVM的体系结构 三、JVM运行时数据区 3.1 PC寄存器 3.2 JVM栈 3.3 堆(Heap) 3.4 方法区域 3.5 运行时常量池 3.6本地方法堆栈 四、Jvm堆 五、Jvm调优

    jvm+ 垃圾算法+垃圾回收概述

    jvm+ 垃圾算法+垃圾回收概述

    JVM内存模型一些简单的概述

    一、JVM内存模型概述 ........................ ........................ 二、程序计数器 ........................ ........................ 三、虚拟机栈 ........................ ........................ 四...

    jvmkill, 资源耗尽时终止 JVM.zip

    jvmkill, 资源耗尽时终止 JVM 概述收费 jvmkill是一个简单的 JVMTI代理,在无法分配内存或者创建线程时强制终止 JVM 。 这对于可靠性目的很重要: 一个 OutOfMemoryError 常常会让JVM处于不一致状态。 终止JVM将允许...

    详细讲解了jvm在java中应用

    主要包含:JVM概述,内存结构讲解,对象实例化,垃圾回收,类的加载,程序编译,代码的优化,性能监控与调优. JVM:全称 Java Virtual Machine,一个虚拟计算机,Java 程序的运行环境(Java二进制字节码的运行环境) 特点:...

    三问JMM--有关JVM内存模型的PPT

    有关JVM内存模型的概述,用于对JVM的整体把握从而针对性的学习

    Java面试需要掌握的JVM知识.docx

    文档内容包括:JVM体系结构概述、JVM内存管理、JVM垃圾回收和JVM常见面试题。希望对大家有帮助!

    node-jvm, 在纯 node.js 中,java虚拟机.zip

    node-jvm, 在纯 node.js 中,java虚拟机 节点 jvm 概述节点 jvm - 纯 node.js 中的jvm示例 javapublic class Main { public static long fib(int n) { if (n &lt;= 1

    深入理解JVM内存结构及运行原理全套视频加资料.txt

    JVM是Java知识体系中的重要部分,对JVM底层的了解是每一位Java程序员深入Java技术领域的重要因素。本课程试图通过简单易懂的方式,系统的深入讲解JVM相关知识。包括JVM执行过程、虚拟机类加载机制、运行时数据区、GC...

    resin-jvm 调优

    1.JVM的gc概述 gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存。java语言并不要求jvm有gc,也没有规定gc如何工作。不过常用的jvm都有gc,而且大多数gc都使用类似的算法管理内存和执行收集操作。 ...

    Java虚拟机(JVM)概述

    因此,我们要做的就是创建一个软件,以软件的形式模拟硬件提供的服务,使之看起来这个特定的硬件在系统中是实际存在的。虚拟机在一定程度上使用CPU虚拟化,为实际的硬件问题提供一个接口。所以可以说它

Global site tag (gtag.js) - Google Analytics