本篇文章给大家带来的内容是关于JVM内存区域和垃圾回收的分析(图文),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
一、JVM简介
JVM,全称Java Virtual Machine,即Java虚拟机。以Java作为编程语言所编写的应用程序都是运行在JVM上的。JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java有个非常重要的特点就是与平台的无关性,而JVM正是实现这一特点的关键。
JVM对程序的执行主要分为两个步骤,第一步是编译,即将.java的源文件编译成为.class的字节码文件,第二步是解释,JVM对字节码文件进行解释执行。两个步骤流程图分别如下两图所示:
二、JVM内存区来源gaodai#ma#com搞@代~码$网域
JVM整个大系统又分为两个子系统。第一个是ClassLoader,即类加载器,功能是将编写的类加载到JVM中。第二个是Execution Engine,即执行引擎,负责对编译后的字节码文件进行解释执行。上述中Execution Engine又分为两部分,第一部分是Runtime data area,即运行时数据区域,即相当于JVM中的内存,第二部分是Native interface,即本地化接口,主要用于执行其他非Java编程语言编写的程序。
重点就是前者Runtime data area,它分为五个部分,分别是Method area(方法区),Heap(堆),VM stack(虚拟机栈),Program counter register(程序计数器),Native method stack(本地方法栈)。前两者线程共享,后三者线程隔离。如下图所示:
概括地说,JVM初始运行的时候都会分配好Method area(方法区)和Heap(堆),而JVM 每遇到一个线程,就为其分配Program counter register(程序计数器)、VM stack(虚拟机栈)、Native method stack(本地方法栈), 当线程终止时,三者(虚拟机栈,本地方法栈和程序计数器)所占用的内存空间也会被释放掉。这也是为什么把数据区域分为线程共享和线程隔离的原因,线程隔离的那三个区域的生命周期与所属线程相同,而线程共享的区域与Java程序运行的生命周期相同,所以这也是系统垃圾回收场所只发生在线程共享的区域(实际上对大部分虚拟机来说是发生在Heap上)的原因。关于内存溢出异常如下图所示:
1、Method area(方法区)
方法区包括常量池与静态域。存放了所加载类的信息(名称、修饰符等)、类的静态变量、类的常量、类的Field信息、类的方法信息。当开发人员在程序中通过Class对象中的getName、isInterface等方法来获取信息时,这些数据都来源于方法区。
2、Heap(堆)
堆是JVM所管理的内存中最大的一块,几乎所有的对象实例和数组都在此区域,可以认为Java中所有通过new创建的对象的内存都在此分配,堆中的对象的内存需要等待GC进行回收。
3、Program counter register(程序计数器)
程序计数器是一块较小的内存空间,它是当前线程所执行的字节码的行号指示器,字节码解释器工作时通过改变该计数器的值来选择下一条需要执行的字节码指令,分支、跳转、循环等基础功能都要依赖它来实现。