Java虚拟机------JVM内存区域

JVM内存区域运行时数据区域分为两种:

JVM内存区域

运行时数据区域分为两种:

  1. 线程隔离的数据区:

    • 程序计数器
    • Java虚拟机栈
    • 本地方法栈
  2. 所有线程程共享的数据区:

    • Java堆

    • 方法区

JVM 内存区域 ———栈介绍

所谓 “栈”包括:Java虚拟机栈,本地方法栈,他们的作用相似,区别只是:

虚拟机栈:虚拟机栈为虚拟机执行Java方法(也就是字节码)服务

本地方法栈: 虚拟机使用到的Native方法服务

程序员人为的分为“堆栈”中的“栈”。

扫描二维码关注公众号,回复: 5273146 查看本文章

栈里存放了编译期可知的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用和指向了一条字节码指令的地址

每个方法在执行的同时都会创建一个栈帧(StackFrame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。

局部变量表所需的内存空间在编译期间完成分配,其中64位的long和double类型的数据会占2个局部变量空间,其余的数据类型只占用1个。当进入一个方法时,这个方法需要在帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。

操作数栈也要操作栈,主要是在方法计算时存放的栈。

JVM 内存区域 ———堆介绍

Java堆(Java Heap)是Java虚拟机所管理的内存中最大的一块,此内存区域就是存放对象实例,几乎所有的对象实例都在这里分配内存。

Java堆是垃圾收集器管理的主要区域;内存回收的角度来看Java堆中还可以细分为:新生代和老年代;新生代细致一点的有Eden空间、From Survivor空间、To Survivor空间。

在实现时,既可以实现成固定大小的,也可以是可扩展的,不过当前主流的虚拟机都是按照可扩展来实现的(通过-Xmx设置最大内存和-Xms设置初始内存)

JVM内存区域-方法区

方法区又叫静态区:用于存储已被虚拟机加载的类信息、常量池、静态变量、即时编译器编译后的代码等数据。虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做Non-Heap(非堆);

对于HotSpot虚拟机是使用永久代来实现方法区;

Java虚拟机规范对方法区的限制非常宽松,除了不需要连续的内存和可以选择固定大小或者可扩展外,还可以选择不实现垃圾收集。相对而言,垃圾收集行为在这个区域是比较少出现的,这区域的内存回收目标主要是针对常量池的回收和对类型的卸载,条件相当苛刻。

public class Test{

public static void main(String[] args){

//s1,s2分别位于堆中不同空间

String s1=new String("hello");

String s2=new String("hello");

System.out.println(s1==s2);//输出false

//s3,s4位于池中同一空间

String s3="hello";

String s4="hello";

System.out.println(s3==s4);//输出true

	}
}

JVM 内存区域——-异常

程序计数器
没有指定任何OutOfMemoryError情况
java虚拟机栈\本地方法栈区域
如果线程请求的栈深度于虚拟机所允许的深度,将抛出StackOverflowError异常;如果扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常

如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常报错后dump出信息: -XX:+HeapDumpOnOutOfMemoryError
方法区
当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常

猜你喜欢

转载自www.cnblogs.com/fmgao-technology/p/10418190.html