摘要:本模块分为四个部分讲解,分别为(1)内存空间;(2)内存分配;(3)内存回收【重点】;(4)内存状况分析。
内存空间是指我们在运行Java程序时,Java源文件通过编译器产生字节码文件在JVM中的运行与存储情况。
内存空间从线程是否共享分为:
线程私有:
1)程序计数器
一块较小的空间,是当前线程所执行的字节码行号指示器,每条线程都有自己的程序计数器,因此它也被称为“线程私有”内存。
2)虚拟机栈
是描述Java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每个方法从调用到执行完成,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
栈帧:是用来存储数据和部分过程结果的数据结构,同时也被用来处理动态链接、方法返回值和异常分派。栈帧随着方法的调用而创建随着方法结束而销毁——无论方法是正常完成还是(抛出了在方法内未被捕获的异常)都算作方法结束。
3)本地方法栈
本地方法区和Java Stack作用相似,区别是虚拟机栈为执行Java方法服务,而本地方法栈则为Native方法服务,如果一个VM实现使用C-linkage模型来支持Native调用,那么栈将会是一个C栈,但HopSpot VM直接就将本地方法栈和虚拟机栈合二为一。
线程共享:
4)方法区/永久代
我们常说的永久代,用于存储被JVM加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。HotSpotVM 把GC分代收集扩展至方法区,即使用Java堆的永久代来实现方法区,这样HopSpot的垃圾收集器就可以像管理Java堆一样管理这一部分内存,而不必为方法区专门开发内存管理器。
运行时常量池是方法区的一部分。class文件除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池,用于存放编译器生成的各种字面量和符号引用,这部分内容在类加载后存放到方法区的运行常量池中。
5)类实例区(Java堆)——运行时数据区
是被线程共享的一块区域,创建的对象和数组都保存在Java堆内存中,也是垃圾收集的最重要的内存区域。由于现代VM采用分代收集算法,因此Java堆从GC角度还可以细分为:新生代(Eden区、From Survivor区和To Survivor区)和老年区。
直接内存:不受JVM GC管理
原文:https://www.cnblogs.com/hjdk05/p/12463941.html