JVM内存区域

2021/7/8 7:06:42

本文主要是介绍JVM内存区域,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

 

 

1. 程序计数器(线程私有)

当前线程所执行的字节码的行号指示器,占用空间小。

线程执行Java方法:计数器记录正在执行的虚拟机字节码指令的地址;

线程执行Native方法:计数器为空。

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

 

2 虚拟机栈(线程私有)

每个方法在执行的同时会创建一个栈帧用于存储对于局部变量表、操作数栈、动态链接、方法出口等信息,然后放入栈中。每个时刻正在执行的当前方法就是虚拟机栈顶的栈帧。方法的执行就是对应着栈帧在虚拟机栈中入栈和出栈的过程。

本区域的两种异常情况:

① StackOverflowError异常:线程请求的栈深度大于虚拟机所允许的深度;

② OutOfMemoryError异常:虚拟机栈动态扩展到无法申请到足够的内存。

 

3 本地方法栈(线程私有)

与虚拟机栈发挥的作用相似,JVM简单的动态链接并直接调用nativa方法;

二者区别是:虚拟机栈为虚拟机执行Java方法(字节码0)服务;

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

本区域的两种异常情况:

① StackOverflowError异常:线程请求的栈深度大于虚拟机所允许的深度;

② OutOfMemoryError异常:本地方法栈动态扩展到无法申请到足够的内存。

 

4 堆(线程共享)

Java虚拟机锁管理内存中最大的一块,所有线程共享的一块区域;

垃圾收集器管理的主要区域,也被称作GC堆;

可用以下参数调整:

-Xms: 堆的最小值;

-Xmx: 堆的最大值;

-Xmn: 新生代的大小;

-XX:NewSize: 新生代最小值;

-XX:MaxNewSize: 新生代最大值;

本区域的异常情况:

① OutOfMemoryError异常:堆无法申请到足够的内存。

 

5 方法区/永久代(线程共享),别名Non-Heap

用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

运行时常量池属于方法区的一部分,用于存放编译期生成的各种字面量和符号引用。

本区域的异常情况:

① OutOfMemoryError异常:方法区无法满足内存分配需求。

 

可用以下参数调整:
jdk1.7及以前:-XX:PermSize;-XX:MaxPermSize;
jdk1.8以后:-XX:MetaspaceSize; -XX:MaxMetaspaceSize
jdk1.8以后大小就只受本机总内存的限制
如:-XX:MaxMetaspaceSize=3M

 

6 直接内存(线程共享)

不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域。如果使用了NIO(New Input/Output),本区域会被频繁的使用。在Java堆中可以用DirectByteBuffer对象作为这块内存的引用进行操作。

这块内存不受java堆大小限制,但受本机总内存的限制,可以通过-XX:MaxDirectMemorySize来设置(默认与堆内存最大值一样),所以也会出现OOM异常。

 

 

 

 

各个版本内存区域的变化

 

 

 

 

 

 

 

 

线程的角度看内存

 

 

深入辨析堆和栈

 

 

 

未完待续...



这篇关于JVM内存区域的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程