JVM内存分区
Posted simpledi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM内存分区相关的知识,希望对你有一定的参考价值。
1、java虚拟机内存结构
java程序的执行依赖于JAVA虚拟机(运行与机器内存中),其开始于一个main()方法,如果在一台机器上运行三个java程序,就需要三个java虚拟机。
1.1 程序计数器
- 功能:一块较小的内存,执行引擎Execution Engine通过改变计数器的值选取下一条需要执行的字节码指令。条件、循环,异常处理等都需要程序计数器来控制。
- 线程私有。单核cpu同一时间只能执行一个线程,多线程程序需要进行线程切换,因此每个线程都需要程序计数器记录自己被执行到了哪一行。
- 异常:唯一一个不会产生异常的区域。
- 备注:如果执行的是native方法,则计数器值为空。
1.2 JVM 栈
- 功能:用于方法的执行。每执行一次一个方法都会创建一个栈帧(从方法被调用到执行完成)入栈,函数调用结束(return或者异常)栈帧出栈,方法A调用方法B,则A入栈后,B入栈,当前正在执行的方法一定在栈顶。包括:存储局部变量表、操作数栈、动态链接、方法出口灯。
- 局部变量表:函数参数、基本类型数据、对象引用(reference)等。
- 操作数栈:计算中间结果。
- 线程私有。生命周期同线程。
- 异常:StackOverflowError(线程请求的栈深度大于虚拟机所允许的深度)和OutOfMemoryError(栈在扩展时无法申请到足够的内存)
1.3 本地方法栈
- 同JVM栈,区别在于本地方法栈为native方法服务。 java通过JNI调用其他语言代码编译得到的动态代码库dll。
1.4 堆
- 功能:存放对象实例。垃圾回收机制管理的主要区域,java堆可以细分为新生代、老生代等分区,分区是为了更好的分配和回收内存,堆不需要连续的内存空间。
- 线程共享。JVM内存中很大的一部分,虚拟机启动时创建。
- 异常:堆中没有内存完成实例分配,并且堆无法再扩展时,抛出OutOfMemoryError异常。
1.5 方法区
- 功能: 存放被加载了的类信息(类的全限定名、父类名、属性信息、方法信息、静态变量信息等),方法区也不需要连续的内存。
- 线程共享。属于垃圾回收机制管辖范围。
- 异常:方法区无法满足内存分配时,抛出OutOfMemoryError异常。
- 备注:运行时常量池也是方法区的一部分,包括字面常量(final)和符号引用(-类和接口的全限定名、-属性名称和描述符、-方法名称和描述符)两部分。
另外:直接内存,其不属于JVM运行时数据区的一部分,但是该内存区域也被频繁的使用,并且也可能导致OutOfMemoryError异常出现。
除程序计数器之外的其他四种内存空间都可以申请动态扩展,因为程序计数器、JVM栈、本地方法栈都是线程私有,因此不需要对其进行垃圾回收,垃圾回收主要针对堆和方法区。
参考文献:https://blog.csdn.net/a910626/article/details/52318590
以上是关于JVM内存分区的主要内容,如果未能解决你的问题,请参考以下文章