Java的内存区域详解。

5 篇文章 0 订阅

1、运行时数据区

Java虚拟机在执行java程序的过程中将它所管理的内存划分为以下几个运行时数据区域:

1、程序计数器(Program Counter Register)

2、虚拟机栈(VM Stack)

3、本地方法栈(Native Method Stack)

4、堆(Heap)

5、方法区(Method Area)

线程私有区域(程序计数器、虚拟机栈、本地方法栈),线程共享区域(堆、方法区),直接内存。线程私有数据区域生命周期与线程相同, 依赖用户线程的启动/结束 而 创建/销毁(在 Hotspot VM 内)。线程共享区域随虚拟机的启动/关闭而创建/销毁。直接内存并不是 JVM 运行时数据区的一部分。如下图:

 

1、程序计数器:

程序计数器是一块较小的内存空间,它可以当作是线程所执行的字节码的行号指令,为了线程切换后能够恢复到正确的执行位置,每条线程都需要一个独立的程序计数器,个线程之间的程序计数器互不影响,各自独立存储。这类内存区域为“线程私有”的区域。此内存区域是唯一一个没有OutOfMemoryError的区域。

2、Java虚拟机栈

与程序计数器一样,Java虚拟机栈也是线程私有的,它的生命周期和线程相同,虚拟机栈描述的是Java方法执行的线程内存模型:每一个方法执行的时候都会同步一个栈帧。用于存储局部变量表,数栈,动态连接,方法出口等信息。每一个方法调用直至被执行完毕,就对应一个栈帧在虚拟机中从入栈到出栈的过程。

这个区域规定了两种异常情况:

 1)、如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverFlowError

 2)、如果虚拟机在扩展时无法申请到足够的内存空间,则抛出OutOfMemoryError异常

3、本地方法栈

本地方法栈与虚拟机栈发挥的作用非常相似,区别在于虚拟机方法栈为虚拟机执行Java方法服务,本地方法栈为虚拟机使用Native方法服务。Hotspot虚拟机将本地方法栈和虚拟机方法栈合二为一。与虚拟机栈一样,本地方法栈在栈深度溢出或者栈扩展失败时分别抛出StackOverFlowError和OutOfMemoryError异常。

4、Java堆

Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。所有创建的对象和数组都存放在堆上。Java堆是垃圾收集器管理的主要区域,垃圾收集器主要基于**分代收集算法**,因此从GC的角度对堆进行划分:新生代(Eden空间、From Survivor空间、To Survivor空间)、老年代。如果在堆中没有内存完成示例分配、并且堆也无法再扩展,将会抛出OutOfMemoryError异常。堆的大小可以通过-Xmx(jvm运行时堆的最大值)和-Xms(jvm运行时堆的最小值)控制。

5. 方法区

1、方法区和Java堆一样,是各个线程的共享区域。方它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

2、运行时常量池是方法区的一部分。Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池(Constant Pool Table),用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池。java虚拟机对class文件每一部分的格式都有严格的规定,每一个字节用于存储哪种数据都必须符号规范上的要求才会被虚拟机认可、装载和执行。当常量池无法申请到内存时会抛出OutOfMemoryError异常。

6. 直接内存(Direct Memory)

直接内存(Direct Memory)并不是虚拟机运行时的数据区的一部分,也不是java虚拟机规范中定义的内存区域,不会受到java堆大小的限制,不受jvm gc的管理。这部分内存如果频繁使用,也可能导致OutOfMemoryError异常, 测试本机直接内存溢出,DirectMemory容量可通过-XX:MaxDirectMemorySize设置,如果不指定,默认与Java堆最大值(-Xmx指定)一样。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值