面试之JVM内存简洁解释

参考了多位CSDN大佬的文章,在本文开头就先跪谢各位大佬的内容!! :)

可以按线程是否私有分为两大类:

  • 线程私有的有程序计数器 (Program Counter Register)虚拟机栈 (Java Stack)本地方法栈 (Native Method Stack)
  • 线程共享的有(Heap)、方法区 (Method Area)

1. JVM 内存整体的结构(运行时数据区)和各自的功能

方法区(Method Area)

它是线程共享的内存区域,它用于存放已被虚拟机加载了的类信息常量静态变量即时编译器编译后的代码等数据,同时方法区还维护了运行时常量池, 以下是相关的一些简单的例子:

Helloword.class (类信息)

常量:

public static final double PI = 3.14; // 静态常量

final int y = 10; // 成员常量

public static void main(String[] args) {

    final double x = 3.3; // 局部成员常量
    ......

}

 
当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常

运行时常量池位于方法区 - 进一步理解常量池可参考文章

JAVA常量池,一篇文章就足够入门了。(含图解)_河海哥yyds的博客-CSDN博客

堆(Heap)

它是线程共享的内存区域,在虚拟机启动时完成创建。这块内存区域的(唯一)目的就是存放对象实例,几乎所有的对象实例和数组都在这里分配内存,也就是说通过new关键字创建的对象都会使用堆内存 (e.g.: new Object(); new int[10])

如果在堆中没有完成实例分配,并且堆也无法扩展时,将会抛出 OutOfMemoryError 异常

程序计数器(Program Counter Register)

它是线程独享的内存区域,它可以被看作是当前线程所执行的字节码的行号指示器。用于保存JVM中下一条所要执行的指令地址 (通俗的讲就是在并发环境中,它负责告诉程序下一步该执行哪一条指令)

此区域是唯一一个虚拟机规范中没有规定任何OutOfMemoryError情况的区域

虚拟机栈(Java Stack,也被叫做非堆 Non-heap)

它是线程独享的内存区域,是每个线程运行都需要的内存空间。

每个方法在执行的时候会创建一个帧栈(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口(Return address)等信息。

局部变量表:

        存放一些基本类型变量(int, byte, short, char, float,double, long, boolean)和对象句柄,他们可以是方法的参数,也可以是方法内部的局部变量 

操作数栈:运算操作等

动态链接:访问其他方法

方法出口:方法返回

它描述了一个方法执行的生命周期 (从方法执行时创建栈帧,并且压入栈,到方法执行完成压出栈),如果在方法中调用了另一个方法,那么就需要去创建另一个全新的栈帧去描述另一个方法的生命周期(入栈出栈。。。)

Java虚拟机栈有两种异常状况︰

1. 如果线程请求的栈的深度大于虚拟机所允许的深度将抛出StackOverflowError异常;

2. 如果扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常。

本地方法栈(Native Method Stack)

它是线程独享的内存区域,是保存一些带有native关键字的方法就是需要JAVA去调用本地的C或者C++方法,因为JAVA没法直接和操作系统底层交互,所以需要用到本地方法

与Java虚拟机栈一样,本地方法栈也会抛出StackOverflowError和 OutOfMemoryError异常

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值