java内存区域①:运行时内存

1.运行时数据区

java虚拟机运行时的数据区
     首先参考这张图片,我们可以清楚地看出常说的堆、栈都处于运行时数据区。同时堆和方法区是线程共享的,而程序计数器(PCR)和栈是线程私有的。

1.1程序计数器

Program Counter Register是当前线程所执行的字节码的行号指示器。每条线程都有一个独立的PCR,彼此之间互不影响。
如果程序执行的是java方法,则计数器值为当前字节码指令地址,如果执行的是native方法,则计数器为空。
程序计数器这部分内存空间是唯一一个不会出现OutOfMemoryError的区域。

1.2虚拟机栈

Java Virtual Machine Stacks的生命周期与线程相同,为线程私有。
局部变量表存放在栈中,其所需要的内存空间在编译器就会完成分配。

  • 局部变量表
    • 基本数据类型(boolean,byte,char,short,int,float,long,double)
    • 对象引用(reference)
    • returnAddress(指向了一条字节码指令的地址)

这个区域可能对应两种异常:

  • 两种异常:
    • StackOverflowError:如果虚拟机栈不允许动态扩展,且线程请求的栈深度大于虚拟机允许的最大深度时触发。
    • OutOfMemoryEroor:如果虚拟机栈可以动态扩展,但是扩展时无法申请到足够的内存时触发。

1.3堆

Heap是内存中最大的一块,被所有线程所共享,唯一的用处就是存放对象实例。
堆也被称为GC堆(Garbage Collected Heap),因为它是垃圾收集器管理的主要区域。从内存回收的角度可以将堆分为新生代和老生代,再细致为Eden,From Survivor和To Survivor.
堆可以处于不连续的内存空间。如果堆中没有内存完成实例分配且堆再也无法拓展时,抛出OutOfMemoryError异常。

1.4方法区

Method Area是线程共享的区域,垃圾回收在这个区域很少出现。它用于存放已经被虚拟机加载的类信息常量静态变量编译器编译后的代码等数据。
方法区不需要连续的内存,也不一定有固定的大小,可以拓展。当方法区无法满足内存分配的需求时,抛出OutOfMemoryError异常。

1.4.1运行时常量

Runtime Constant Pool是方法区的一部分,用于存放编译期生成的各种字面量和符号引用。

1.5直接内存

Direct Memory不属于运行时数据区,甚至不属于虚拟机中的内存取悦。它是利用通道和缓冲区的I/O方式,使用native函数库分配堆外内存,然后通过堆中的DirectByteBuffer对象作为这块内存的引用进行操作。
把直接内存放这里一起记录,是因为它还是会收到本机内存的限制,从而导致动态拓展时可能抛出OutOfMemoryError.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值