精华内容
下载资源
问答
  • JVM运行机制

    2019-08-02 09:59:13
    JVM运行机制 首先要知道jvm是由五大部分组成,分别是类装载子系统,运行时数据区,执行引擎,本地方法接口和内存回收机制 先是类装载子系统,它把所有引用到的类,接口以及包一起装载到文件下 然后是最...

    JVM运行机制

    首先要知道jvm是由五大部分组成,分别是类装载子系统,运行时数据区,执行引擎,本地方法接口和内存回收机制

    • 先是类装载子系统,它把所有引用到的类,接口以及包一起装载到文件下

    • 然后是最重要的运行时数据区
      :JVM由主方法入口执行程序,并将主方法压入java栈,并生成该方法相应的栈桢,然后由程序计数器提供的指令来一步步执行
      :执行中遇到调用java方法则将其压入java栈中,遇到变量赋值,就存储在局部变量表中,遇到表达式,则用操作数栈来进行运算,并将结果弹出栈返回,遇到调用其它类时,就用动态链接,遇到本地方法则调用本地方法栈,遇到常量对象时,将其分配到运行时常量池中,遇到实例化对象时,先获取方法区中的类信息,然后在堆当中给其分配相应的空间
      :堆当中,根据流行的分代GC算法,可以将其分为两部分:新生代和老年代
      :新生代又分为Eden,s1,s2,其中新对象一般都分配在Eden中,当Eden内存不足时,会触发MinorGC(清完无用对象后,把Eden和s1中幸存的对象复制到s2,s2放不下就放老年代,再清空二者,最后s1和s2互换),对象在s区中每度过一次GC年龄加1,到指定值时放入老年代(默认15岁)
      :老年代相对稳定,它在内存不足或无法给大对象分配连续空间时会触发Major GC(用标记-整理算法来清理内存,速度相对缓慢),当老年代内存还是不足时,会抛出outofmemory异常
      :永久代是用来存放clss和元数据的信息,且GC 不会在主程序运行期对永久区域进行清理
      在这里插入图片描述

    展开全文
  • jvm运行机制

    2020-02-07 20:51:46
    JVM运行在操作系统之上,不与硬件设备直接交互。 Java源文件在通过编译器之后被编译成相应的.Class文件(字节码文件),.Class文件又被JVM中的解释器编译成机器码在不同操作系统上运行。每种操作系统的解释器各不...

    JVM是用于运行Java字节码的虚拟机,包括一套字节码指令集,一组程序寄存器,一个虚拟机栈,一个虚拟机堆,一个方法区及一个垃圾回收器。JVM运行在操作系统之上,不与硬件设备直接交互。

     Java源文件在通过编译器之后被编译成相应的.Class文件(字节码文件),.Class文件又被JVM中的解释器编译成机器码在不同操作系统上运行。每种操作系统的解释器各不相同,但基于解释器実現的虚拟机是相同的,這也是Java能跨平台的原因。在一个一个Java进程开始运行后,虚拟机就开始実例化了,有多个进程启动就実例化多个虚拟机実例。进程退出或者关闭,则虚拟机実例消亡,在多个虚拟机实例之间不能共享数据。

    Java程序的具体运行过程:

    ①Java源文件被编译器编译成字节码文件。

    ②JVM将字节码文件编译成相应操作系统的机器码

    ③机器码调用相应操作系统的本地方法库执行相应的方法

    JVM构成如下:

    其中,

    ● 类加载器子系统用来将编译好的.Class文件加载到JVM中;

    ● 运行时数据区用于存储在JVM运行过程中产生的数据,包括程序计数器、方法区、本地方法区、虚拟机栈及虚拟机堆;

    ● 执行引擎包括即时编译器和垃圾回收器,即时编译器用于将java字节码编译成具体的机器码,垃圾回收器用于回收运行时不再使用的对象。

    ● 本地接口库用于调用操作系统的本地方法库完成具体的指令操作。

    展开全文
  • JVM 运行机制及其原理发布时间:2018-05-22 22:15,浏览次数:1074, 标签:JVM最近出去面试,总被问到JavaJVM相关的东西,什么JVM的内存模型、JVM的内存分配、内存回收、内存回收算法…搞得我一头雾水,早些年还看过...

    JVM 运行机制及其原理

    发布时间:2018-05-22 22:15,

    浏览次数:1074

    , 标签:

    JVM

    最近出去面试,总被问到Java

    JVM相关的东西,什么JVM的内存模型、JVM的内存分配、内存回收、内存回收算法…搞得我一头雾水,早些年还看过一些,蹭着有时间给大家也给自己总结下JVM相关的知识。

    JVM

    JVM是Java Virtual

    Machine(Java虚拟机)的缩写,是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java虚拟机主要由字节码指令集、寄存器、栈、垃圾回收堆和存储方法域等构成。

    JVM屏蔽了与具体操作系统平台相关的信息,使Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。JVM在执行字节码时,实际上最终还是把字节码解释成具体平台上的机器指令执行。

    JVM声明周期

    JVM伴随Java程序的开始而开始,程序的结束而停止。一个Java程序会开启一个JVM进程,一台计算机上可以运行多个程序,也就可以运行多个JVM进程。

    JVM将线程分为两种:守护线程和普通线程。守护线程是JVM自己使用的线程,比如垃圾回收(GC)就是一个守护线程。普通线程一般是Java程序的线程,只要JVM中有普通线程在执行,那么JVM就不会停止。

    JVM内存模型组成

    JVM内存模型主要由堆内存、方法区、程序计数器、虚拟机栈和本地方法栈组成,其组成的结构如下图所示。

    其中,堆和方法区是所有线程共有的,而虚拟机栈,本地方法栈和程序计数器则是线程私有的。

    堆内存

    堆内存是所有线程共有的,可以分为两个部分:年轻代和老年代。下图中的Perm代表的是永久代,但是注意永久代并不属于堆内存中的一部分,同时jdk1.8之后永久代也将被移除。

    堆内存是我们在生产环境中进行内存性能调优中的一个重要的内容,而内存回收的一些机制和算法也是常见的考点,大家可以访问下面的链接:Java性能优化之JVM GC

    方法区

    方法区与Java堆一样,是各个线程共享的区域,它用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译(JIT)后的代码等数据。

    由于程序中所有的线程共享一个方法区,所以访问方法区的信息必须确保线程是安全的

    。如果有两个线程同时去加载一个类,那么只能有一个线程被允许去加载这个类,另一个必须等待。

    在程序运行时,方法区的大小是可以改变的,程序在运行时可以扩展。同时,方法区里面的对象也可以被垃圾回收,但条件非常严苛,必须在该类没有任何引用的情况下才能被GC回收。

    程序计数器

    在JVM的概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。

    JVM的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,为了各条线程之间的切换后计数器能恢复到正确的执行位置,所以

    每条线程都会有一个独立的程序计数器。

    当线程正在执行一个Java方法,程序计数器记录的是正在执行的JVM字节码指令的地址;如果正在执行的是一个Natvie(本地方法),那么这个计数器的值则为空(Underfined)。

    程序计数器占用的内存空间很少,也是唯一一个在JVM规范中没有规定任何OutOfMemoryError(内存不足错误)的区域。

    Java虚拟机栈

    与程序计数器一样,Java虚拟机栈也是线程私有的,用通俗的话将它就是我们常常听说到堆栈中的那个“栈内存”。虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(Stack

    Frame)用于存储局部变量表(局部变量表需要的内存在编译期间就确定了所以在方法运行期间不会改变大小),操作数栈,动态链接,方法出口等信息。每一个方法从调用至出栈的过程,就对应着栈帧在虚拟机中从入栈到出栈的过程。

    本地方法栈

    栈作为一种线性的管道结构,遵循先进后出的原则。主要用于存储本地方法的局部变量表,本地方法的操作数栈等信息。当栈内的数据在超出其作用域后,会被自动释放掉。

    本地方法栈是在程序调用或JVM调用本地方法接口(Native)时候启用。

    Java类加载机制

    什么是类加载

    众所周知,JVM加载的是.class文件。其实,类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构。类的加载的最终产品是位于堆区中的Class对象,Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口。

    同时,JVM规范允许类加载器在预料某个类将要被使用时就预先加载它,如果在预先加载的过程中遇到了.class文件缺失或存在错误,类加载器会在程序首次主动使用该类时会生成错误报告(LinkageError错误),如果这个类一直没有被程序主动使用,那么类加载器就不会报告错误。

    类的加载过程

    JVM将类的加载分为3个步骤:

    1、装载(Load)

    2、链接(Link)

    3、初始化(Initialize)

    而链接(Link)又分3个步骤:

    1,验证

    2,准备

    3,解析

    可以使用下面的图像表示。

    1,装载

    加载是类加载过程的第一个阶段,在加载阶段,虚拟机需要完成以下三件事情:

    1、通过一个类的全限定名来获取其定义的二进制字节流。

    2、将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。

    3、在Java堆中生成一个代表这个类的java.lang.Class对象,作为对方法区中这些数据的访问入口。

    相对于类加载的其他阶段而言,加载阶段是获取类的二进制字节流的最佳阶段,因为开发人员既可以使用系统提供的类加载器来完成加载,也可以自定义自己的类加载器来完成加载。

    加载阶段完成后,虚拟机外部的

    二进制字节流就按照虚拟机所需的格式存储在方法区之中,而且在Java堆中也创建一个java.lang.Class类的对象,这样便可以通过该对象访问方法区中的这些数据。

    2,链接

    链接阶段分为三个步骤:验证、准备和解析。

    * 验证:确保被加载的类的正确性;

    * 准备:为类的静态变量分配内存,并将其初始化为默认值;

    * 解析:把类中的符号引用转换为直接引用。

    验证

    验证是链接第一步,这一阶段的目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。验证阶段大致会完成4个阶段的检验动作:

    * 文件格式验证

    :验证字节流是否符合Class文件格式的规范;例如:是否以0xCAFEBABE开头、主次版本号是否在当前虚拟机的处理范围之内、常量池中的常量是否有不被支持的类型。

    * 元数据验证

    :对字节码描述的信息进行语义分析(注意:对比javac编译阶段的语义分析),以保证其描述的信息符合Java语言规范的要求;例如:这个类是否有父类,除了java.lang.Object之外。

    * 字节码验证:通过数据流和控制流分析,确定程序语义是合法的、符合逻辑的。

    * 符号引用验证:确保解析动作能正确执行。

    验证阶段是非常重要的,但不是必须的,它对程序运行期没有影响,如果不需要验证,那么可以考虑采用-Xverifynone参数来关闭大部分的类验证措施,以缩短虚拟机类加载的时间。

    准备

    准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些内存都将在方法区中分配。对于该阶段有以下几点需要注意:

    1、这时候进行内存分配的仅包括类变量(static),而不包括实例变量,实例变量会在对象实例化时随着对象一块分配在Java堆中。

    2、这里所设置的初始值通常情况下是数据类型默认的零值(如0、0L、null、false等),而不是被在Java代码中被显式地赋予的值。

    解析

    解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程,解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用限定符7类符号引用进行。符号引用就是一组符号来描述目标,可以是任何字面量。

    直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄。

    3,初始化

    初始化,为类的静态变量赋予正确的初始值,JVM负责对类进行初始化,主要对类变量进行初始化。在Java中对类变量进行初始值设定有两种方式:

    1,声明类变量是指定初始值。

    2,使用静态代码块为类变量指定初始值。

    类的初始化步骤或JVM初始化的步骤如下:

    1)如果这个类还没有被加载和链接,那先进行加载和链接 ;

    2)假如这个类存在直接父类,并且这个类还没有被初始化(注意:在一个类加载器中,类只能初始化一次),那就初始化直接的父类(不适用于接口);

    3 ) 假如类中存在初始化语句(如static变量和static块),那就依次执行这些初始化语句。

    Class加载器

    JVM的类加载是通过ClassLoader及其子类来完成的,类的层次关系和加载顺序可以由下图来描述。

    Bootstrap ClassLoader

    负责加载$JAVA_HOME中 jre/lib/rt.jar

    里所有的class或Xbootclassoath选项指定的jar包。由C++实现,不是ClassLoader子类。

    Extension ClassLoader

    负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar 或 -Djava.ext.dirs指定目录下的jar包。

    App ClassLoader

    负责加载classpath中指定的jar包及 Djava.class.path 所指定目录下的类和jar包。

    Custom ClassLoader

    通过java.lang.ClassLoader的子类自定义加载class,属于应用程序根据自身需要自定义的ClassLoader,如tomcat、jboss都会根据j2ee规范自行实现ClassLoader。

    展开全文
  • JVM 运行机制

    2018-05-03 10:11:43
    jvm 启动流程启动类java xxx ---> 装载配置 ---> 根据配置找到jvm.dll -->初始化JVM获得JNIEnv接口-->找到main方法 ( 根据当前路 jvm.dll 是jvm JNIEnv为 jvm 接口 径和系统版 ...

    jvm 启动流程


    启动类

    java xxx ---> 装载配置 --->  根据配置找到jvm.dll -->初始化JVM获得JNIEnv接口-->找到main方法

                      ( 根据当前路        jvm.dll 是jvm                    JNIEnv为 jvm 接口

                         径和系统版           主要实现                        findClass等操作通过它

                        本寻找jvm.cfg                                          实现

                         )

    jvm基本结构


    执行引擎执行字节码

    pc寄存器

    每个线程拥有过一个pc寄存器

    在线程创建时创建

    指向下一条指令地址

    执行本地方法的时候,pc的值为undefined


    方法区(用来描述一个类)

    保存了状态类的信息                     jdk6时, string等常量信息 至于方法

        类型常量池                              jdk7  已经移动到了堆栈

        字段,方法信息

         方法字节码           

    通常和永久区关联在一起    

    java堆

    和程序开发密切相关,

    应用系统的对象保存在堆中 

    所有线程共享java堆

    对于分代gc来水,堆也是分代的

    java栈

    线程私有

    栈是由一系列帧组成(java 栈也叫帧栈) 先进后出

    帧保存一个方法的局部变量、操作数栈、常量池指针

    每一次方法调用创建一个帧,并压栈。


    java栈中 局部变量表


    静态的函数  表 中很多槽位,最大容纳32位的数据类型  long由64位 2个槽位 对象传的指针

    普通函数 。第一个数this指针


    每次函数调用都会产生一个帧,递归调用时候不断的往上压

    局部变量表,与操作数栈



    c++ 在栈上分配内存,不需要释放 ,借鉴到java上






    java 栈上分配

    小对象(几个是byte) 在没有逃逸的情况下,可以分配到栈上

    直接分配到栈上, 可以自动回收,较少gc压力

    大对象和逃逸对象无法在栈上分配

    逃逸情况指的是 多个线程共有的对象要在堆上分配


    栈 、 队、方法区的交互情况



    内存模型

    每个线程都有自己的工作内存和主存

    主存就是大家共享的内存空间,考虑效率问题,每个线程都有自己的工作区间

    当数据从主存复制到工作存储时候,1 read 2 load




     注意volatile 使用


    如果不使用volatile 程序会一直的跑着


    线程的可见性

    线程的有序性和指令重拍,有些可以重拍有些不可以






    字节码两种执行方式



                                


    展开全文
  • JVM上执行java字节码,执行时这些字节码可以解释成具体平台的机器码,学习JVM运行机制以及原理,会懂得为什么java语言拥有“一次编译,处处运行”这一跨平台能力。什么是JVM呢?JVM是Java VirtualMachine(Java虚拟机)...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,507
精华内容 4,202
关键字:

jvm运行机制