Jvm 内存区域详解

Jvm 内存区域划分


运行时数据区:Java程序启动时系统内存分配的一块独立的内存区域,其中可分为两部分:线程共享部分和线程独享部分,那么下面便根据这样的划分规则来介绍一下各个内存区域的作用以便后面提到的Java运行原理做一下准备。

首先线程共享部分顾名思义,多个线程都可以访问的内存区域,其中包含方法区和堆内存,既然是内存区域那么肯定使用存放数据的,那么这两块内存区域到底是用来存放什么的呢?

  • 方法区:

用于存储已经被加载的类的信息、常量、静态变量和JIT编译后的代码等数据,包含(运行时常量池)。

其中被加载后的类的信息稍后会提到,这里简单介绍一下JIT编译:JIT即为即时编译(Just In Time Complier),在没有JIT的情况下,Java必须将.java文件经过编译器编译成.class字节码文件,然后交由jvm解释执行,此时可称之为纯解释型语言,那么便会在热点代码(重复执行、循环)的情况产生效率问题,此时引入JIT编译器,jvm读入.class文件后进行热点探测并交由JIT编译器编译,JIT会将热点代码编译成机器指令并缓存,每次调用热点代码便可直接执行。

  • 堆内存:

堆是jvm中最大的一块内存,用于存放对象,对象是有生命周期的,所以在此处也会伴随着GC的运行。因此堆还可将其细分为新生代和老年代,这便涉及到Java垃圾回收机制,所涉篇幅沾多,会单独拿出来细说,遍不在此介绍。

上述方法区和堆内存都为线程共享部分,那么下面就说说线程独享部分,线程独享即为伴随线程产生而产生,线程销毁而销毁,所以此部分的内存空间不涉及到多线程并发的情况,也是我们做线程封闭的常用手段。

  • 程序计数器:

是一块内存较小的区域,用于记录当前线程所执行的字节码指令的位置。

  • 虚拟机栈:

用于存放对应方法的栈帧。从其存储的数据就可以知道,虚拟机栈实际上就是描述的Java方法执行的内存模型。当线程执行某个方法时遍会创建一个栈帧用于存储局部变量表、操作栈、动态链接和方法出口等信息,所以每一个方法的执行都是对应的栈帧在虚拟机栈中的入栈和出栈操作。

  • 本地方法栈:

和虚拟机栈类似,只是虚拟栈中执行的是Java的字节码指令,而本地方法栈中执行的是系统自带的Native方法。