初识JVM及jvm运行时数据区和jvm内存模型的区别

        众所周知Java从95年出世之后就一直处于语言排行榜的 top 前几位,最主要的原因是因为Java的内存管理机制,我们coding 只管new 对象(前提是正常编码)从来基本没有考虑过对象怎么存在,如何销毁释放等问题。其次就是Java 的跨平台性,准确来说应该是Java一次编译多处运行,是基于不同操作系统安装不同的Java运行所需的jvm才能完成如此强大的跨平台运行。

       学习jvm之前先来普及一下jdk、jre、jvm三者的联系和作用:JDK(Java Development Kit) 是 Java 语言的软件开发工具包(SDK),主要用于移动设备、嵌入式设备上的java应用程序。JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具。JRE为Java Runtime Environment的简称,Java Runtime Environment(包括Java Plug-in)是Sun的产品,包括两部分:Java Runtime Environment和Java Plug-in。JavaRuntimeEnvironment(JRE)是可以在其上运行、测试和传输应用程序的Java平台。它包括Java虚拟机(jvm)、Java核心类库和支持文件。它不包含开发工具(JDK)--编译器、调试器和其它工具。JRE需要辅助软件--Java Plug-in--以便在浏览器中运行appletJVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。


相信如果之前对jvm不是太了解的应该也会多少明白些。下面就认识一下jvm的运行时数据区和jvm的内存模型。

jvm运行时数据区

                                                                                                                     

 程序计数器(Program Counter (PC) Register):官方解释是指向当前线程正在执行的字节码指令的地址、行号。明明说了当前线程正在执行的字节码,为什么还要存储它的地址行号呢?原因是CPU工作的原理是有任务调度的,有可能该字节码没有执行完毕就被挂起啦,这样解释可能就容易理解了。

 虚拟机栈(Java Virtual Machine Stacks)栈是一种数据结构,数据结构是存储数据的,因此虚拟机栈就是当前线程运行方法是所需的数据、指令以及返回地址。虚拟机栈是first in last out,里面的每执行一个方法就是一个栈帧,递归的方法(进过实例测试递归多少次就会有多少栈帧)。

      本地方法栈 (Native Method Stacks):本地方法栈与虚拟机栈发挥的功能非常类似,只是虚拟机栈为虚拟机执行java方法而服务,而本地方法栈为虚拟机执行native方法而服务。与虚拟机栈一样,本地方法栈也会抛出 StackOverflowError 和OutOfMemoryError异常。任何本地方法接口都会使用某种本地方法栈。当虚拟机调用java方法时,虚拟机会创建一个栈帧并且压入虚拟机栈;当虚拟机调用本地(native)方法时,虚拟机不会创建新的栈帧,虚拟机栈会保持不变,虚拟机只是简单的动态连接并直接调用相关的本地方法。

      方法区(Method Area):方法区在JVM中也是一个非常重要的区域,它与堆一样,是被线程共享的区域。在方法区中,存储了每个类的信息(包括类的名称、方法信息、字段信息)、静态变量、常量以及编译器编译后的代码等。在方法区中有一个非常重要的部分就是运行时常量池,它是每一个类或接口的常量池的运行时表示形式,在类和接口被加载到JVM后,对应的运行时常量池就被创建出来。当然并非Class文件常量池中的内容才能进入运行时常量池,在运行期间也可将新的常量放入运行时常量池中,比如String的intern方法。

       (Heap Memory)堆数据区是用来存放对象和数组(特殊的对象)。堆内存由多个线程共享。堆内存随着JVM启动而创建。众所周知,Java中有一个很好的特性就是自动垃圾回收。垃圾回收就操作这个数据区来回收对象进而释放内存。如果堆内存剩余的内存不足以满足于对象创建,JVM会抛出OutOfMemoryError错误。

1. 存储的全部是对象,每个对象包含一个与之对应的class信息–class的目的是得到操作指令。 
      2. jvm只有一个堆区(heap)被所有线程共享,堆区中不存放基本类型和对象引用,只存放对象本身。 
      3. 堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。 

      4. 缺点是,由于要在运行时动态分配内存,存取速度较慢。

jvm的内存模型

颜色和jvm运行时数据区上面的一致就代表那个区域,

Heap(Java堆)

几乎所有对象实例和数组都要在堆上分配(栈上分配、标量替换除外), 因此是VM管理的最大一块内存, 也是垃圾收集器的主要活动区域. 由于现代VM采用分代收集算法, 因此Java堆从GC的角度还可以细分为: 新生代(Eden区From Survivor区To Survivor区)和老年代; 而从内存分配的角度来看, 线程共享的Java堆还还可以划分出多个线程私有的分配缓冲区(TLAB). 而进一步划分的目的是为了更好地回收内存和更快地分配内存.

Method Area(方法区)

即我们常说的永久代(Permanent Generation), 用于存储被JVM加载的类信息常量静态变量即时编译器编译后的代码等数据. HotSpot VM把GC分代收集扩展至方法区, 即使用Java堆的永久代来实现方法区, 这样HotSpot的垃圾收集器就可以像管理Java堆一样管理这部分内存, 而不必为方法区开发专门的内存管理器(永久带的内存回收的主要目标是针对常量池的回收类型的卸载, 因此收益一般很小)

如有披露或问题欢迎留言或者入群探讨


猜你喜欢

转载自blog.csdn.net/qq_39470733/article/details/80935743
今日推荐