JVM篇[1]浅谈Jvm基于JDK8

it2025-09-10  6

从Java开发角度去分析的话我们必须要了解jvm中的各个模块与jvm中的内存处理机制(GC垃圾回收机制)。本文旨在介绍jvm。

JVM 是什么呢? 通俗讲就是Java代码编译出来的class文件,计算机并不能直接加载,这个时候怎么办呢,就需要jvm去做解析加载了,把字节码文件中的逻辑加载到内存,这就是jvm做的事情。 接下来看下百度百科的专业回答。 JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。 引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。 –百度百科

2. jvm中的运行时数据区

也就是本文介绍的重点 jvm中的五大模块 程序计数器 – 线程私有 虚拟机栈 – 线程私有 堆 – 数据共享 方法区 – 数据共享 本地方法栈 – 线程私有 简述 jvm会为每个线程分配自己的程序计数器,虚拟机栈,本地方法栈。当前线程执行完毕,三者(程序计数器,虚拟机栈,本地方法栈)的内存区域也随之被释放。这三者(程序计数器,虚拟机栈,本地方法栈)线程私有 、生命周期短暂。而堆区和方法区中占用的内存不会马上回收,最先要确保当前对象无引用才能开始清除,当然也就是GC处理机制中对于垃圾的定义:当前实例是否还有引用。 2.1 程序计数器 线程私有,占用内存空间小。里面存储的是当前线程需要执行的下一条字节码指令。 2.2 虚拟机栈 线程私有,每个java方法在调用时都会在内存中创建一个栈帧区,用于存储当前方法内部引用变量和基本数据类型。创建栈帧区时内存不够用的话会抛出StackOverflowError 和 OutOfMemoryError 异常。 栈中的变量指向堆内存中的变量,这就是 Java 中的指针! 虚拟机栈记录的是当前对象在堆区中的引用。

//obj 栈中的引用变量 指向 new Object(); 在堆内存中创建一片地址存储Object Object obj = new Object();

2.3 堆 数据共享。java对象,数组初始化后存储的区域。如果创建对象超过当前可用内存会抛出OutOfMemoryError 简单解释就是在堆内存中开辟一片空间存储当前实例。 java的GC自动回收处理会将堆区分区,年轻代,年老代,(基于1.7版本的话会有永生代,)1.8之后加入了方法区,从这方面看的话实际上方法区就是永生代,实际上永生代也会进行GC扫描。 楼主会从用下一篇文章单独介绍垃圾回收。 这里我们了解了堆栈后可以再简单看下== 与 equals的区别就比较有趣了 我们知道== 比较的是当前变量与另一个变量在jvm中存储地址是否是同一个,equals比较的是具体的值。了解堆栈后更容易理解的就是==是栈中存储变量引用地址的比较,equals是堆区中数据的比较。 引用数据类型如String、Integer等等在直接赋值初始化时有优化策略,并不会直接存入堆区。加载下面代码运行下你会觉的更有趣。

/** ** String 是不可变性对象,创建出来,字符串连接+,字符串切割 都会重新在堆区new一个新的对象。 为避免重复创建string对象,在同一个jvm内,string初始化时数据是共享(可以避免大量重复的string被不断创建) integer 对象在创建时 byte([-128 - 127])类型范围内的数值 会存放在一个公共的缓存区, 源码中可以看到IntegerCache内部类具体实现。 */ public static void main(String[] args) { String aa= "aa"; String bb = "aa"; //true System.out.println(aa == bb); String cc = new String(aa); //false System.out.println(aa == cc); Integer ii1 = 127; Integer ii2 = 127; //true System.out.println(ii1 == ii2); Integer nii1 = new Integer(ii1); Integer nii2 = new Integer(ii1); //false System.out.println(nii1 == nii2); Integer ii3 = 128; Integer ii4 = 128; //false System.out.println(ii3 == ii4); }

2.4 方法区 数据共享。存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。 jdk7中对于方法区的定义其实是持久代,jvm分代思想是为了GC(垃圾回收)为什么要分代这些我们下篇文章再说,最主要的原因是为了提升GC效率,防止内存中碎片化严重。 在方法区中有一个非常重要的部分就是运行时常量池,用于存放静态编译产生的字面量和符号引用。运行时生成的常量也会存在这个常量池中,比如String的intern方法。它是每一个类或接口的常量池的运行时表示形式,在类和接口被加载到JVM后,对应的运行时常量池就被创建出来。 2.5 本地方法栈 jvm采用本地方法栈来支持native方法的执行。虚拟机栈保证的是java方法的执行,本地方法栈是为执行本地方法(native)服务的

最后感谢 https://www.cnblogs.com/qianjinyan/p/10352749.html https://blog.csdn.net/know9163/article/details/80574488

最新回复(0)