JVM内存区域划分

本文详细介绍了JVM内存的划分,包括程序计数器、虚拟机栈、本地方法栈、堆、方法区(包含常量池)以及直接内存。各区域的作用、线程共享或私有特性以及可能产生的异常如StackOverflowError和OutOfMemoryError均进行了阐述。
摘要由CSDN通过智能技术生成

java虚拟机在执行java程序的时候,会将管理的内存区域划分成若干个不同的数据区域

  • 程序计数器

可以看成是当前线程执行字节码指令的行号指示器,字节码解释器工作时,是通过改变这个指示器的值来选取下一条执行的字节码命令,分支,循环,跳转,异常处理以及线程恢复都是需要这个计数器来完成。
程序计数器是线程私有,因为java的多线程本质上是在同一时刻是由一个处理器(内核)来进行时间片的轮转来实现的,那么,当一个线程执行完之后,切换到另外一个线程,为了防止各个线程之间相互干扰,那么每个线程内部都会有一个程序计数器。
如果线程执行的是java方法,那么这个程序计数器指向的是正在执行的虚拟机字节码的指令地址,如果是Native方法,那么值为undefined ,这个区域是唯一一个没有定义out of memory的区域。

1.java 虚拟机栈 虚拟机为java方法服务
java虚拟机栈是线程私有的,生命周期和线程相同。
java虚拟机栈描述的是Java方法执行时的内存模型:每个方法在执行时都会创建一个帧栈(Stack Frame),用于局部变量表,操作数栈,动态链接,方法出口等信息,每一个方法的调用直至执行完成的过程,都对应着,一个帧栈在虚拟机中从入栈到出栈的过程。
局部变量表存放:基本数据类型,对象引用,以及returnAddress的地址(指向了一条指令字节码的地址),由于这些都是固定的,所以局部变量表在编译期间内完成内存的分配,在方法执行期间保持不变。
两种异常:StackOverflowError和OutOfMemoryError
如果线程请求的栈深度大于虚拟机的栈深度,那么就会StackOverflowError
如果虚拟机的栈是可以动态扩展的,那么,当申请的满足不了要求的时候,就会出现OutOfMemoryError
思考:1.方法执行时,具体的过程,以及内存的分配? 2.为什么是stack frame,怎么理解?
链接
2.本地方法栈 虚拟机为本地Native服务
同样也会出现StackOverflowError和OutOfMemoryError

java堆是线程共有的,几乎所有的对象实例和数组都在堆上进行分配,是GC的主要区域。
由于GC很多采用的是分代回收的算法,所以java堆可以细分为:Eden,From Surivivor,To Surivivor
可能出现 OutOfMemoryError

  • 方法区(Method Area)

和java堆一样,是线程共享区域。
用于存储,已经被虚拟机加载的类信息,常量,静态变量和即时编译后的代码等数据。
方法区的内存回收主要是针对常量池的回收以及类型的卸载,一般这个区域内存的回收效果常常不是那么 满意,尤其是类型卸载的时候,条件非常的严格。但是对这个区域的回收也是必要的,否则会出现内存泄漏的bug。
可能出现OutOfMemoryError

  • 常量池(Constant Pool Table)

方法区的一个部分,用于存放编译期生成的各种字面常量和符号引用,这部分内容将在类加载后进入运行时的常量池中存放。
可能出现OutOfMemoryError。

  • 直接内存(Direct Memory)

直接内存并不是虚拟机运行时数据区的一个部分,也不是java虚拟机规范中的定义的内存区域。但是这部分的内存也被频繁的调用,因此,也可能导致OutOfMemoryError。
在JDK1.4后,新加入了NIO(New Input/Output)类,是一种基于channel与缓冲区的IO方式,它可以使用Native库直接分配堆外内存,然后通过一个存储在堆中的DirectByteBuffer对象来作为这块内存的引用进行操作,加快了速度,但是也会出现OutOfMemoryError.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值