码迷,mamicode.com
首页 > 编程语言 > 详细

Java内存区域与内存溢出异常

时间:2016-01-03 19:32:27      阅读:217      评论:0      收藏:0      [点我收藏+]

标签:

运行时数据区域

 技术分享

程序计数器(Program Counter Register:可看作是当前程序所执行的字节码的行号指示器。在虚拟机的概念模型里(不同虚拟机可能有不同的实现方法),字节码解释器就是通过改变程序计数器的值来取下一条字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖于这个计数器。

Java虚拟机栈(Java Virtual Machine Stacks):与程序计数器一样,Java虚拟机栈也是线程私有的,他的它的生命周期和线程相同,虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用到执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

有人把Java内存分为堆(Heap)内存和栈(Stack)内存,而“栈”就是现在讲的虚拟机栈。局部变量表存放了相关局部变量,包括基本数据类型、对象引用和返回地址等。

虚拟机栈包括两种异常,StackOverflowError:所请求的栈深度大于虚拟机栈允许的最大深度。OutOfMemoryError:虚拟机栈扩展时无法申请到足够内存。

本地方法栈(Native Method Stacks:本地方法栈与虚拟机栈十分类似,不同之处在于虚拟机栈为虚拟机执行Java方法服务,而本地方法栈为虚拟机执行Native method服务,在有的虚拟机中直接将本地方法栈和虚拟机栈合二为一了。

Java堆(Heap:虚拟机管理内存中最大的一块,很多时候也被称为GC堆,Java堆被所有线程所共享,它在虚拟机启动时创建,用于存放对象实例。从内存回收角度看,该区又可细分为Eden空间、From Survivor空间和To Survivor空间,从内存分配角度看,该区可能划分出多个线程私有的分配缓冲区(Thread Local Allocation Buffer,TLAB)。Java堆可以处于物理上不连续的内存空间中(逻辑上连续即可),目前主流的虚拟机的堆都是可扩展的(-Xms、-Xmx),若堆中内存不足以完成实例分配,也无法再扩展时,会抛出OutOfMemoryError异常。

方法区(Method Area:方法区也是各个线程所共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、编译器即时编译的代码等数据。方法区的内存回收目标主要针对常量池的回收和对类型的卸载,当方法区无法满足内存分配需求时,会抛出OutOfMemoryError异常。

运行时常量池(Runtime Constant Pool:运行时常量池是方法区的一部分,常量池(Constant Pool Table)用于存放编译期生成的各种字面量和符号引用,在类加载后进入方法区的运行时常量池中存放。

直接内存(Direct Memory:直接内存不是Java虚拟机定义的内存区域,在JDK1.4中新加入了NIO(New Input/Output)类,引入了一种基于通道与缓冲区的IO方式,它可以使用Native函数库直接分配堆外内存,然后通过存储在Java堆中的DirectByBuffer对象引用这块内存,直接内存不受Java堆大小限制,只受本机总内存和处理器寻址空间的限制

 

参考资料:《深入理解Java虚拟机 JVM高级特性与最佳实践》

Java内存区域与内存溢出异常

标签:

原文地址:http://www.cnblogs.com/yaokaiyang/p/5096906.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!