【转】JVM介绍

1. 什么是JVM?

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java虚拟机包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域。 JVM屏蔽了与具体操作系统平台相关的信息,使Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。JVM在执行字节码时,实际上最终还是把字节码解释成具体平台上的机器指令执行。

Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码。而引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。这就是Java的能够“一次编译,到处运行”的原因。

2. JRE/JDK/JVM是什么关系?

JRE(JavaRuntimeEnvironment,Java运行环境),也就是Java平台。所有的Java 程序都要在JRE下才能运行。普通用户只需要运行已开发好的java程序,安装JRE即可。

JDK(Java Development Kit)是程序开发者用来来编译、调试java程序用的开发工具包。JDK的工具也是Java程序,也需要JRE才能运行。为了保持JDK的独立性和完整性,在JDK的安装过程中,JRE也是 安装的一部分。所以,在JDK的安装目录下有一个名为jre的目录,用于存放JRE文件。

JVM(JavaVirtualMachine,Java虚拟机)是JRE的一部分。它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM有自己完善的硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。Java语言最重要的特点就是跨平台运行。使用JVM就是为了支持与操作系统无关,实现跨平台。

3. JVM原理

JVM是java的核心和基础,在java编译器和os平台之间的虚拟处理器。它是一种利用软件方法实现的抽象的计算机基于下层的操作系统和硬件平台,可以在上面执行java的字节码程序。

java编译器只要面向JVM,生成JVM能理解的代码或字节码文件。Java源文件经编译成字节码程序,通过JVM将每一条指令翻译成不同平台机器码,通过特定平台运行。

4. JVM执行程序的过程

1) 加载.class文件 2) 管理并分配内存 3) 执行垃圾收集

JRE(java运行时环境)由JVM构造的java程序的运行环,也是Java程序运行的环境,但是他同时一个操作系统的一个应用程序一个进程,因此他也有他自己的运行的生命周期,也有自己的代码和数据空间。JVM在整个jdk中处于最底层,负责于操作系统的交互,用来屏蔽操作系统环境,提供一个完整的Java运行环境,因此也就虚拟计算机。操作系统装入JVM是通过jdk中Java.exe来完成,通过下面4步来完成JVM环境:1) 创建JVM装载环境和配置 2) 装载JVM.dll 3) 初始化JVM.dll并挂界到JNIENV(JNI调用接口)实例4) 调用JNIEnv实例装载并处理class类。

5. JVM的生命周期

1) JVM实例对应了一个独立运行的java程序它是进程级别
a) 启动。启动一个Java程序时,一个JVM实例就产生了,任何一个拥有public static void
main(String[] args)函数的class都可以作为JVM实例运行的起点
b) 运行。main()作为该程序初始线程的起点,任何其他线程均由该线程启动。JVM内部有两种线程:守护线程和非守护线程,main()属于非守护线程,守护线程通常由JVM自己使用,java程序也可以表明自己创建的线程是守护线程
c) 消亡。当程序中的所有非守护线程都终止时,JVM才退出;若安全管理器允许,程序也可以使用Runtime类或者System.exit()来退出

2) JVM执行引擎实例则对应了属于用户运行程序的线程它是线程级别的

6. JVM的体系结构

  • 类装载器(ClassLoader)(用来装载.class文件)
  • 执行引擎(执行字节码,或者执行本地方法)
  • 运行时数据区(方法区、堆、java栈、PC寄存器、本地方法栈)

7. JVM运行时数据区

第一块:PC寄存器

PC寄存器是用于存储每个线程下一步将执行的JVM指令,如该方法为native的,则PC寄存器中不存储任何信息。

第二块:JVM栈

JVM栈是线程私有的,每个线程创建的同时都会创建JVM栈,JVM栈中存放的为当前线程中局部基本类型的变量(java中定义的八种基本类型:boolean、char、byte、short、int、long、float、double)、部分的返回结果以及Stack Frame,非基本类型的对象在JVM栈上仅存放一个指向堆上的地址。

第三块:堆(Heap)

它是JVM用来存储对象实例以及数组值的区域,可以认为Java中所有通过new创建的对象的内存都在此分配,Heap中的对象的内存需要等待GC进行回收。

(1) 堆是JVM中所有线程共享的,因此在其上进行对象内存的分配均需要进行加锁,这也导致了new对象的开销是比较大的

(2) Sun Hotspot JVM为了提升对象内存分配的效率,对于所创建的线程都会分配一块独立的空间TLAB(Thread Local Allocation Buffer),其大小由JVM根据运行的情况计算而得,在TLAB上分配对象时不需要加锁,因此JVM在给线程的对象分配内存时会尽量的在TLAB上分配,在这种情况下JVM中分配对象内存的性能和C基本是一样高效的,但如果对象过大的话则仍然是直接使用堆空间分配

(3) TLAB仅作用于新生代的Eden Space,因此在编写Java程序时,通常多个小的对象比大的对象分配起来更加高效。

(4) 所有新创建的Object 都将会存储在新生代Yong Generation中。如果Young Generation的数据在一次或多次GC后存活下来,那么将被转移到OldGeneration。新的Object总是创建在Eden Space。

第四块:方法区域(Method Area)

(1)在Sun JDK中这块区域对应的为PermanetGeneration,又称为持久代。

(2)方法区域存放了所加载的类的信息(名称、修饰符等)、类中的静态变量、类中定义为final类型的常量、类中的Field信息、类中的方法信息,当开发人员在程序中通过Class对象中的getName、isInterface等方法来获取信息时,这些数据都来源于方法区域,同时方法区域也是全局共享的,在一定的条件下它也会被GC,当方法区域需要使用的内存超过其允许的大小时,会抛出OutOfMemory的错误信息。

第五块:运行时常量池(Runtime Constant Pool)

存放的为类中的固定的常量信息、方法和Field的引用信息等,其空间从方法区域中分配。

第六块:本地方法堆栈(Native Method Stacks)

JVM采用本地方法堆栈来支持native方法的执行,此区域用于存储每个native方法调用的状态。

8. JVM垃圾回收

GC (Garbage Collection)的基本原理:将内存中不再被使用的对象进行回收,GC中用于回收的方法称为收集器,由于GC需要消耗一些资源和时间,Java在对对象的生命周期特征进行分析后,按照新生代、旧生代的方式来对对象进行收集,以尽可能的缩短GC对应用造成的暂停

(1)对新生代的对象的收集称为minor GC;

(2)对旧生代的对象的收集称为Full GC;

(3)程序中主动调用System.gc()强制执行的GC为Full GC。

不同的对象引用类型, GC会采用不同的方法进行回收,JVM对象的引用分为了四种类型:

(1)强引用:默认情况下,对象采用的均为强引用(这个对象的实例没有其他对象引用,GC时才会被回收)

(2)软引用:软引用是Java中提供的一种比较适合于缓存场景的应用(只有在内存不够用的情况下才会被GC)

(3)弱引用:在GC时一定会被GC回收

(4)虚引用:由于虚引用只是用来得知对象是否被GC


原文转自:【转】JVM介绍 - myLittleGarden - 博客园 (cnblogs.com)icon-default.png?t=M4ADhttps://www.cnblogs.com/sunada2005/p/3577799.html

<think>嗯,用户想了解JVM的基本概念和工作原理。首先,我需要明确JVM的定义,它是Java虚拟机的缩写,是Java程序运行的核心。接下来,要分步骤解释它的工作原理。记得用户提到需要结构清晰,所以应该按照流程来组织内容,比如编译、加载、执行、内存管理、垃圾回收这些环节。 首先,JVM的作用是实现跨平台,这点很重要,用户可能已经知道Java的“一次编写,到处运行”,但需要解释JVM如何做到这点。然后,从Java源代码编译成字节码开始,类加载器的作用,这部分需要引用已有的资料,比如引用[3]提到类加载器加载字节码到内存,可以引用这个。 接下来是执行引擎,解释器逐行解释字节码,但为了优化性能,JIT编译器会将热点代码编译成机器码,这里需要提到引用[4]中的JIT优化手段。内存管理部分要分堆和栈,堆用于对象实例,栈用于方法调用,引用[2]提到内存模型和垃圾回收机制,可以引用这里的相关内容。 垃圾回收机制是JVM的重要部分,需要说明自动内存管理的原理,以及不同的GC算法。可能用户对GC如何工作感兴趣,但不需要深入细节,保持基础解释即可。 用户的问题还包括如何工作,所以整个流程需要连贯:从编写代码到编译成.class文件,类加载器加载到内存,执行引擎处理,内存分配和回收。每个步骤都需要简明扼要,避免过于技术化,但确保准确性。 还需要注意使用中文回答,所有数学公式用$...$,独立公式用$$...$$,但当前问题可能不涉及太多数学内容,不过如果有提到算法或性能分析可能需要应用。不过JVM原理更多是概念性的,可能用不上数学公式,但需要检查是否有必要的地方。 另外,用户要求生成相关问题,所以最后要准备几个相关问题,比如JVM内存结构、类加载过程、垃圾回收算法、调优方法等,参考已有的引用内容,比如引用[4]提到了JIT优化,引用[2]提到调优技术,可以围绕这些生成问题。 最后,确保引用标识正确添加到对应的内容后面,例如在解释类加载器时引用[3],内存管理引用[2],执行引擎引用[4]等。检查所有引用是否准确,没有遗漏。 总结下来,回答的结构应该是:定义JVM,跨平台特性,工作流程分步骤解释,每个步骤引用相关文献,最后列出相关问题。保持语言简洁,符合用户要求的清晰结构。</think>### JVM 基本概念与工作原理解析 #### **JVM 是什么?** Java虚拟机(Java Virtual Machine, JVM)是Java技术的核心组件,负责执行编译后的Java字节码(`*.class`文件)。它的核心目标是实现**跨平台运行**,即“一次编写,到处运行”。通过将字节码换为特定平台的机器指令,JVM屏蔽了底层操作系统的差异[^1][^3]。 --- #### **JVM 如何工作?** JVM的工作流程可分为以下关键步骤: 1. **编译阶段** Java源代码(`.java`文件)通过编译器(如`javac`)换为**字节码**(`.class`文件),字节码是独立于平台的中间代码。 $$ \text{Java源码} \xrightarrow{\text{编译}} \text{字节码} $$ 2. **类加载** 类加载器(ClassLoader)将字节码加载到JVM内存中,包括以下过程: - **加载**:读取字节码文件。 - **验证**:确保代码符合JVM规范。 - **准备**:为静态变量分配内存并初始化默认值。 - **解析**:将符号引用换为直接引用。 - **初始化**:执行静态代码块和赋值操作[^4]。 3. **执行引擎** - **解释器**:逐行解释字节码为机器指令执行。 - **即时编译器(JIT)**:将频繁执行的代码(热点代码)编译为本地机器码以提升性能。 ```java // 示例:JIT优化的热点代码 for (int i = 0; i < 1000000; i++) { calculate(i); // 多次调用后触发JIT编译 } ``` 4. **内存管理** JVM通过运行时数据区管理内存: - **堆(Heap)**:存储对象实例,是垃圾回收的主要区域。 - **栈(Stack)**:存储方法调用时的局部变量和操作数。 - **方法区(Method Area)**:存储类元数据、常量池等[^2]。 5. **垃圾回收(GC)** JVM自动回收不再使用的对象内存,常见的算法包括: - 标记-清除(Mark-Sweep) - 复制算法(Copying) - 分代收集(Generational)[^2]。 --- #### **核心原理总结** JVM通过**类加载、执行引擎、内存管理、垃圾回收**四大机制,为Java程序提供高效、稳定的运行环境。其跨平台能力依赖于字节码和平台相关的JVM实现,而性能优化则通过JIT编译与分代GC实现[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值