JVM运行时数据区域

 

JVM运行时数据区域

    Java虚拟机在运行Java程序的过程中会把它所管理的内存划分为多个不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时间。本文将带你理解JVM的各大数据区域以及用途。

01

程序计数器

    程序计数器是线程私有的,它的主要作用是记录当前线程执行到了那一条指令。线程有可能因为时间片轮转的关系导致挂起,或者是线程上下文切换,这个时候就需要记录下一条执行的指令。

02

Java虚拟机栈

    与程序计数器类似,Java虚拟机栈也是线程私有的,它与线程的生命周期相同。换句话说,线程终止Java虚拟机栈将会消失。Java虚拟机栈主要存储局部变量表、操作数栈、动态连接等。

    考虑到栈,一般都是有栈深的。一个程序是递归调用而没有终止,将会导致线程请求的栈深大于虚拟机所允许的栈深,那么将会抛出StackOverflowError异常。有意思的是,每一次执行程序栈的深度都不一样。
    栈除了StackOverflowError异常外,如果没有足够的内存来扩展,将会抛出OutOfMemoryError异常。

03

本地方法栈

    不同于Java虚拟机栈,本地方法栈中执行的方法都是Native方法,主要是C或者C++语言写的程序。与Java虚拟机栈相似的,这个区域依然会抛出StackOverflowError和OutOfMemoryError异常。

04

Java堆

    如果把JVM运行时区域分为两大块,一份是非堆,另外一份则是堆。Java堆是JVM管理内存的最大一块,也是线程共享的一块区域。在这块区域上。分配了内存用于存放几乎所有的对象实例和数组。由于这个区间分配对象空间,垃圾回收的主要地方也是该区域。

    Java堆可以分为新生代和老年代,再细致一点可以分为Eden空间、FromSurvivor空间、To Survivor空间。

Java堆.png

    可以通过(-Xmx和-Xms)来控制Java堆的大小,如果没有内存来分配对象,将会抛出OutOfMemoryError。

05

方法区

    方法区和Java堆一样是线程共享的,它主要存储已被JVM加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

    可以通过-XX:MaxPermSize提高这个区域的大小,避免OutOfMemoryError异常。

06

运行时常量池

   运行时常量池作为作为方法区的一部分,主要存储编译生成的各种字面量和符号引用。如果有废弃的常量,也会被垃圾回收器回收。

    运行时常量池也会受内存大小限制,会抛出OutOfMemoryError异常。

07

直接内存

    直接内存不属于JVM运行数据的一部分,是在JDK1.4以后NIO类的加入后引入一种基于通道和缓冲区的I/O方式。这样做的好处是在某些场景下,避免了应用程序空间和本地空间之间数据的复制,提高了性能。

    如果这部分内存频繁使用,可能导致OutOfMemoryError异常

08

总结

    Java虚拟机的运行时内存区域主要分为程序计数器、Java虚拟机栈、本地方法栈、堆和方法区。其中,程序计数器和Java虚拟机栈都是线程私有的,堆和方法区是线程共享的。当然,方法区中还有运行时常量池,主要用于存储常量。

    直接内存的引用在是由于NIO类的加入,在某些场景下可以避免数据复制次数。提高性能。

2019_02_22_1933083452.png

点击上方蓝色字体,关注我们

15

好看你就点点我

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值