JVM(6)之运行时数据区域 + 内存溢出异常

一、前言

首先我们来看一张JVM内存区域图:

接下来我们分别来介绍一下这个几个区域的主要作用:

2、程序计数器

程序计数器(program Count Register)是一块较小的内存,它可以看做是当前线程所执行的字节码的行号指示器。字节码解释器工作就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,它是控制控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都是需要依赖这个计数器来完成。

需要注意的是,这个程序计数器是每条线程都需要有一个独立的程序计数器,如果线程正在执行的是一个java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址,如果正在执行的是本地方法,那么这个计数器的值为空。

3、Java虚拟机栈

        与程序计数器一样,Java虚拟机栈(Java Virtual Machine Stack)也是线程私有的,他的生命周期与线程相同,每个方法被执行的时候,Java虚拟机栈会同步创建一个栈帧用于存储:局部变量表、操作数栈、动态链接、方法出口等。每一个方法呗调用直至执行完毕,就对应这一个栈帧在虚拟机中从入栈到出栈的过程。

 4、本地方法栈

        本地方法区和虚拟机栈(Java Stack) 作用类似,区别是虚拟机栈为执行 Java 方法服务,而本地方法栈则为 Native 方法服务,如果一个 JVM 实现使用 C-linkage 模型来支持 Native 调用,那么该栈将会是一个 C 栈,但 HotSpot VM 直接就把本地方法栈和虚拟机栈合二为一。

5、Java堆

        对于Java应用程序来讲,Java堆(Java Heap)是虚拟机所管理的内存中最大的一块,Java堆是被所有的线程共享的一块内存区域。

        Java堆是垃圾收集器管理的内存区域,因此有些地方也叫做是"GC 堆",从回收的角度来讲,由于现代垃圾回收器大部分是基于分代收集理论设计的,所以Java堆中经常会出现“新生代”,“老年代”“永久代”“Eden 空间”“From Survivor空间”“To Survivor空间”等名词,这些区域的划分仅仅是一部分垃圾收集器的共同特性或者设计风格而已,而非某个Java虚拟机具体实现的固有内存布局,更加不是java虚拟机规范里对Java堆的进一步细致划分。

        Java堆既可以被实现成固定大小的,也可以可扩展的,不过当前主流的Java虚拟机都是按照可扩展的来实现的(通过-Xms 和-Xmx设定),如果在Java堆中没有内存完成实例分配,并且也无法再扩展的时候,Java虚拟机将会抛出OutOfMemoryError异常。

 6、方法区

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

        这里说到方法区就不得不说一下“永久代”,尤其是在JDK8 之前,许多java程序员更愿意把方法区称呼为"永久代"两者混为一谈,其实本质上两者是不等价的,只能说永久代是方法区的一种实现,这样子使得垃圾收集器能够象管理Java堆一样管理这部分内存。

        到了JDK7已经把原本放在永久代的字符串常量池、静态变量等移至Java堆,而到了JDK8终于完全放弃了永久代的概念,而是用元空间来替代。

7、运行时常量池

        运行时常量池(Runtime Constant Pool)是方法区的一部分。Class文件除了又累的版本、字段、方法、接口等描述信息外,还有一项是常量池表用于存放编译器生成的各种字面量与符号引用,这部分内容将在类加载后放到方法区的运行时常量池。

8、直接内存

        直接内存(Direct Memory)并不是虚拟机运行时内存区域的一部分,也是不是Java虚拟机规范中定义的内存区域,但是这部分内存也被频繁的使用而且也可能是导致OutOfMemoryError异常出现。

        Java1.4新加入了NIO,引入了一种基于通道与缓冲区的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在JAVA堆的DirectByteBuffer对象作为这块内存区域的引用进行操作。这样子就能显著的提高性能,因为避免了在Java堆和Native堆中来回复制数据。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值