1、JVM的概念
虚拟机是模拟执行某种指令集体系结构(ISA)的软件,是对操作系统和硬件的一种抽象。java虚拟机就是对计算机系统结构的一种简单模拟。
Java虚拟机(JVM)是由Java虚拟机规范定义的,其上运行的是字节码指令集。这种字节码指令集包含一个字节的操作码(opcode),零至多个操作数(oprand),虚拟机规范明确定义了每种字节码指令完成的功能是什么以及需要多少个操作数。Java虚拟机上运行的class文件,这个文件中包含字节码指令流以及类定义的信息,所以Java虚拟机规范还定义了class文件的格式(精确到每个字节)。所以实现Java虚拟机的两个要素是字节码指令集和class文件格式,Java虚拟机的实现者只要以正确方式读取class文件中的每一条字节码指令,并按照要求实现字节码指令的功能就可以实现JVM。
目前常用的商用JVM主要有:Sun HotSpot,BEA JRocket以及IBM J9。其中由于BEA和Sun已经被Oracle收购,所以Oracle拥有当今世界上最流行的两个JVM,并有传言说Oracle将在Java8时将两个虚拟机合并,各取所需,取长补短,打造一个更加精湛的JVM。HotSpot会以解释+即时编译执行代码,HotSpot在解释执行字节码的时候,会探测热点(hotspot)代码,然后将这部分代码编译为本地代码,之后将直接运行本地代码,而不是解释,这样会有效提高虚拟机性能。JRocket主要是定位于服务器应用,所以不关注虚拟机的启动速度,它会将所有代码即时编译为本地代码执行,JRocket的垃圾收集器具有很高的收集效率。J9定位与HotSpot类似,专注于桌面应用和服务器应用,主要是针对IBM的各种Java产品。
2、java语言与虚拟机
java源代码,即.java文件,通过javac编译为.class文件。.class文件load到JVM中,JVM底层会通过字节码解释器或者即时编译器(JIT Compiler)执行.class文件中的字节码指令。JVM是运行在操作系统之上的,操作系统又通过指令集调用底层硬件服务执行其上的各种软件。如下图所示:
java语言并不是只能运行在JVM之上,只要实现了对应的编译器,它可以直接运行在各种操作系统平台上;同样JVM也并不是只能运行java语言,JVM关注的只是字节码能否被正确执行,而不会关心是由哪种语言转换而来的字节码。
3、Java虚拟机体系结构
当java虚拟机运行一个程序时,它需要内存来存储许多东西。例如,字节码、class文件中的信息、对象、方法参数、返回值及运算中间结果等,而这些东西都存储在运行时数据区,便于管理。不同虚拟机的实现对应的内存分配、管理会有所不同。
每个java虚拟机实例都有一个方法区和堆,它们由该虚拟机实例共享,当虚拟机装载一个class文件时,它会将其中的类型信息存放到方法区,当程序运行时创建的对象都会放到堆中。当每一个线程被创建时,它都会分配PC计数器、Java栈。PC寄存器用来指向下一条将被执行的指令,Java栈用来存储该线程中java方法调用的状态(参数、返回值、中间结果等)。而本地方法的调用是依赖于具体实现的方式存储在本地方法栈中或其它寄存器、特定实现的存储中。
1>方法区
被装载类型的信息都会存储在这块内存中。它会存储以下信息:
1、类型的全限定名
2、类型的直接超类的全限定名
3、类型是类类型还是接口类型
4、类型的访问修饰符
5、任何直接超类接口的全限定名的有序列表
6、常量池、字段信息、方法信息、类静态变量
7、类ClassLoader的引用
8、Class类的引用
2> 堆
Java程序在运行时所创建的所有类实例或数组都放在同一个堆中。一个java虚拟机实例中只有存在一个堆,所以所有线程共享一个堆。所以同一个JAVA程序的多个线程共享着同一个堆空间,此时需要考虑对象的同步问题。虚拟机在红有分配对象的指令,却没有释放对象内存的指令。内存的释放是由垃圾收集器去执行,根据不同的JVM实现,他们的垃圾回收策略不一样。
一般情况下堆中会存放指向对象池的指针和指向类数据的指针、对象池实例数据,这样就可以找到类数据和对象数据,从而执行对应的实例方法。还有一种特定的虚拟机实现,堆中除了存储上述数据还会额外存储对象的方法表指针,因为方法表可以存储实例方法运行时所需的所有信息,这样便可以提高运行效率,但是需要花费更多的内存空间来存储。
3> 程序计数器
每个线程都有它自己的PC寄存器,当线程启动时就会被创建,并且指向下一条指令的地址(也可以是相对方法字节码中起始指令地址的偏移量)。当线程执行的是本地方法时,此时存储的是undefined。例如java异常的finnally的实现,是通过在对应的程序计数器中存储一个类型为returnaddress的地址实现的。
4> Java栈
每启动一个新线程,Java虚拟机都会为它分配一个Java栈,用来存储线程的运行状态,虚拟机只会对栈进行2种操作:压栈和出栈。当java线程运行时,执行一个Java方法,虚拟机就会在该线程的Java栈中压入一个新帧,这个帧用来存储参数、局部变量、中间结果等,同时跟踪到当前类和当前常量值,再通过弹出帧来执行当前的实例方法。
5>本地方法栈
它是用来存储一些跟本地方法相关的数据。而本地方法时依赖于虚拟机设计者的具体实现,它可以自由地决定使用怎样的机制来让java程序调用本地方法。
6>执行引擎
任何java虚拟机的实现的核心就是执行引擎,它是用来定义指令集的。对于每条指令如何处理都是由执行引擎来定义并执行的。JAVA程序的每一个线程都是一个独立的虚拟机执行引擎的实例,从线程生命周期的开始到结束,它要么在执行字节码,要么在执行本地方法。
7>本地方法接口
Java虚拟机并不强制必须实现本地方法接口。有些可以根本不支持本地方法接口,有些支持少数几个。而sun的java本地接口称作JNI,是为可移植性准备的。JNI是可以被任何java虚拟机实现支持的,开发者可以扩展或取代JNI,但是新的实现必须跟JAVA虚拟机内部的工作进行某种程度的交互,包括传递返回数据、操作数组、装载新类、抛出异常等。
4、JVM执行程序的流程
在命令行执行"java Main"就会开启一个JVM实例,我们可以通过jps,jstat等JVM工具观察JVM的运行状态,下面以运行com.ntes.money.Main这个类为例来描述一下JVM执行一个程序的流程。
当在命令行执行"java -Xmx=12m -Xms=12m -Dname=value com.ntes.money.Main"这个命令时,JVM的执行流程是,
(1)加载JVM,主要是加载动态链接库,windows下是jvm.dll,Linux下是libjvm.so;(2)设置JVM启动参数,比如命令中的-Xmx=12m -Xms=12m用于设置堆大小。
(3)初始化JVM。
(4)调用类加载器子系统,加载com.ntes.money.Main。这里给出的是自定义类,根据类加载器双亲委派链,最后是由系统默认类加载器(Classpath类加载器)进行加载。 bootstrap loader ->扩展类加载器(ext.jar)->系统类加载(rt.jar)->用户自定义类加载。
(5)在方法区com.ntes.money.Main类对应的数据结构中,根据方法描述符及访问标志,查找main方法。这里的描述符,包括了方法的方法名、参数、返回值,也就是public static void main(String[])。如果找不到对应的main方法,会抛出NoSuchMethodError: main异常。
(6)通过本地方法(JNI)执行main方法。
最后,JVM的自动内存管理,根据不同JVM的实现有所不同。关于典型的hotspot虚拟机堆内存分配,参看另一篇文章:http://rainforc.iteye.com/admin/blogs/1993310
相关推荐
1. **JVM内存结构** JVM内存主要分为以下几个区域: - **方法区(Method Area)**:这是所有线程共享的区域,存储类信息、常量、静态变量、即时编译后的代码等。在Java 8以前,这部分也被称为永久代(Permanent ...
### JVM内存结构详解 #### 一、概述 Java虚拟机(JVM)作为Java程序的运行环境,其核心组件之一便是内存管理系统。理解JVM的内存布局对于开发高性能的应用程序至关重要。本文将详细介绍JVM内存结构及其各个组成部分...
JVM 内存结构和 6 大区域 JVM 是 Java虚拟机,它是 Java 语言的核心组件之一,为 Java 程序提供了运行环境。JVM 的内存结构是 Java 程序的基础,它的设计和实现对 Java 程序的性能和可靠性产生了深远的影响。 JVM ...
"Jvm性能优化-JVM内存结构原理分析03" Jvm性能优化是Java虚拟机(JVM)中非常重要的一部分,它对Jvm的性能产生了很大的影响。本文将从Jvm内存结构的角度来分析Jvm性能优化的原理。 Jvm内存结构主要分为五部分:堆...
JVM内存结构的理解对于优化Java程序性能、避免内存溢出等问题至关重要。以下是对JVM内存结构的详细阐述: 1. **堆内存(Heap)** 堆内存是Java程序中最大的一块内存区域,用于存储对象实例。所有通过`new`关键字...
总之,深入理解JVM内存结构及其管理机制,有助于我们编写更高效、更稳定的Java程序,并能有效地处理内存相关问题。这份"JVM内存结构笔记"将详细阐述这些内容,是学习和研究JVM内存管理的重要参考资料。
总结来说,Linux和JVM内存结构分析是提升系统效率和稳定性的重要手段。通过阅读和分析上述文件,我们可以深入了解系统资源的使用情况,进而进行针对性的调优。对于IT专业人士而言,掌握这些知识不仅能提升工作效率,...
了解JVM内存结构对于优化代码性能、防止内存泄漏以及理解程序运行时的行为至关重要。本文将深入探讨JVM内存的各个区域,帮助你全面掌握JVM的工作原理。 首先,JVM内存主要分为以下几个部分: 1. **程序计数器...
JVM内存结构-JVM体系结构 程序计数器 虚拟机栈 本地方法栈 堆 方法区
2019最新深入理解JVM内存结构及运行原理(JVM调优)高级核心课程视频教程下载。JVM是Java知识体系中的重要部分,对JVM底层的了解是每一位Java程序员深入Java技术领域的重要因素。本课程试图通过简单易懂的方式,系统...
Java虚拟机(JVM)内存结构是理解Java...总之,JVM内存结构是Java平台的核心特性,它为程序提供了动态的内存分配和管理,确保了程序的稳定性和效率。深入理解这一结构,有助于开发者写出更高效、更健壮的Java应用程序。
Java内存模型(JMM)与JVM内存结构不同,它是针对多线程环境下内存访问的抽象模型。JMM确保在多线程环境下,共享变量的读写操作具有正确的顺序和可见性,通过volatile、synchronized等关键字来实现这一目标。JMM关注...
java jvm内存结构 调优
理解JVM内存结构和垃圾回收机制对于Java开发者至关重要,它可以帮助我们更好地优化程序性能,避免内存溢出等问题。通过调整JVM参数,如堆大小、新生代与老年代的比例、垃圾收集器的选择等,我们可以根据应用的需求...
了解JVM内存结构及其功能对于优化Java应用程序的性能和排查内存问题至关重要。 首先,我们来详细探讨JVM的内存结构。在Java中,内存主要分为以下几个区域: 1. **程序计数器(Program Counter Register)**:每个...
在JDK8中,JVM内存结构发生了显著变化,尤其是元空间(MetaSpace)替代了永久代(Permanent Generation)作为方法区的一部分。这种方法区的调整是由于永久代存在的一些问题,比如大小设定困难,容易引发溢出,以及给...
2019最新深入理解JVM内存结构及运行原理(JVM调优)高级核心课程视频教程下载。JVM是Java知识体系中的重要部分,对JVM底层的了解是每一位Java程序员深入Java技术领域的重要因素。本课程试图通过简单易懂的方式,系统...
jvm内存结构-栈的变化,机器指令的格式/执行模式文章中的demo代码。