JVM内存区域详解
本文分为两部分:一是JVM内存区域的讲解;二是常见的内存溢出异常分析。
1.JVM内存区域
java虚拟机在执行java程序的过程中会把它管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途,这些区域有哪些呢?如下图:
1.1 程序计数器
程序计数器是一块很小的内存空间,它的作用可以看作是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。分支,循环,跳转,异常处理,线程恢复等基础功能都需要依赖这个程序计数器。我们知道,在任意一个时刻,一个处理器只能执行一个线程中的指令,当线程切换后,怎么才能恢复到正确的执行位置呢?就需要用这个程序计数器,各个线程之间的程序计数器相互独立,互不影响,我们一般称这块内存区域为 “线程私有”的内存。如果线程执行的是一个java方法,那么程序计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器值为空。此内存区域是唯一一个在java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。
1.2 java虚拟机栈
虚拟机栈描述的是java方法执行的内存模型:每个java方法被执行的时候,都会创建一个栈帧,用于存储局部变量表,操作栈,动态链接,方法出口等信息。每个方法从被调用到执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。虚拟机栈也是线程私有的,它的生命周期与线程相同。我们平时所说的栈内存,就是指虚拟机栈,或者说是虚拟机栈中的局部变量表部分。局部变量表存放了编译期可知的八种基本数据类型,对象引用和returnAddress类型。局部变量表所需要的内存空间是在编译期完成分配,当进入一个方法时,这个方法需要在帧中占用的局部变量空间是确定的,在方法运行期间不会改变局部变量表的大小。其中,64位长度的long和double会占用两个局部变量空间(Slot),其余的数据类型占用1个。在java虚拟机规范中,对这块区域规定了两种异常情况:1.如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常;2 如果虚拟机栈可以动态扩展,当扩展时无法申请到足够的内存,会抛出OutOfMemoryError异常。
1.3 本地方法栈
本地方法栈和虚拟机栈发挥的作用是相似的,虚拟机栈是虚拟机为执行java方法服务,本地方法栈是虚拟机为执行本地Native方法服务。它也会抛出StackOverflowError和OutOfMemoryError异常。
1.4 java堆
java堆是被所有线程共享的一块内存区域,它是java虚拟机所管理的最大的一块内存,在虚拟机启动的时候创建。几乎所有的对象实例都是在这里分配内存,java堆是垃圾收集器管理的主要区域,所以又被成为GC堆。根据java虚拟机规范的规定,java堆可以处于物理上不连续的内存空间,只要逻辑上连续即可。当堆中没有内存可以完成实例分配,并且也无法扩展时,将会抛出OutOfMemoryError异常。
1.5 方法区
方法区也是各个线程共享的内存区域,它主要是存储已经被虚拟机加载的类信息,常量,静态变量等数据。对于习惯在HotSpot虚拟机上部署程序的开发者来说,方法区也被成为永久代。垃圾收集行为在这块区域是很少出现的,这块区域的内存回收主要是针对常量池的回收和对类型的卸载。当方法区无法满足对内存分配的需求时,将抛出OutOfMemoryError异常。
1.6 运行时常量池
运行时常量池是方法区的一部分,Class文件中除了有类的版本,字段,接口和方法等信息外,还有一项信息是常量池。用于存放编译期生成的字面量和符号引用,这部分内容将在类加载后存放到方法区的运行时常量池。当常量池无法申请到内存时,也会抛出OutOfMemoryError异常。
JVM内存区域详解的更多相关文章
- JVM内存区域详解(Eden Space、Survivor Space、Old Gen、Code Cache和Perm Gen)
JVM区域总体分两类,heap区和非heap区.heap区又分为: Eden Space(伊甸园). Survivor Space(幸存者区). Old Gen(老年代). 非heap区又分: Cod ...
- JVM 内存溢出详解(栈溢出,堆溢出,持久代溢出、无法创建本地线程)
出处: http://www.jianshu.com/p/cd705f88cf2a 1.内存溢出和内存泄漏的区别 内存溢出 (Out Of Memory):是指程序在申请内存时,没有足够的内存空间供 ...
- Java(JVM运行时)各种内存区域详解及扩展
本文整理于 Java内存与垃圾回收调优 Java 堆内存 从几个sample来学习Java堆,方法区,Java栈和本地方法栈 首先来一张图让我们理清楚java运行时状态: 诚然,如上图所示:java ...
- JVM虚拟机20:内存区域详解(Eden Space、Survivor Space、Old Gen、Code Cache和Perm Gen)
1.内存区域划分 根据我们之前介绍的垃圾收集算法,限定商用虚拟机基本都采用分代收集算法进行垃圾回收.根据对象的生命周期的不同将内存划分为几块,然后根据各块的特点采用最适当的收集算法.大批对象死去.少量 ...
- JVM内存结构详解
从java编程语言说起... 1. Java编程语言简介 1.1 编程语言概述 系统级和应用级 系统级:C,C++,go,erlang 应用级:C#,Java,Python,Perl,Ruby,php ...
- JVM内存配置详解
前段时间在一个项目的性能测试中又发生了一次OOM(Out of swap sapce),情形和以前网店版的那次差不多,比上次更奇怪的是,此次搞了几天之后啥都没调整系统就自动好了,死活没法再重现之前的O ...
- jvm内存GC详解
一.相关概念 a. 基本回收算法 1. 引用计数(Reference Counting) 比较古老的回收算法.原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数.垃圾回收时,只用收 ...
- JVM内存配置详解(转)
前段时间在一个项目的性能测试中又发生了一次OOM(Out of swap sapce),情形和以前网店版的那次差不多,比上次更奇怪的是,此次搞了几天之后啥都没调整系统就自动好了,死活没法再重现之前的O ...
- JVM内存参数详解以及配置调优
基本概念:PermGen space:全称是Permanent Generation space.就是说是永久保存的区域,用于存放Class和Meta信息,Class在被Load的时候被放入该区域He ...
随机推荐
- 批量修改mac系统文件的可读写权限
www 修改 /Users/feiwang 文件夹下的www 下的所有文件和文件的可读写权限.
- [android] 相对布局和单位简介
/**********************2016年4月23日 更新*******************************/ 知乎:为何Android的默认布局是RelativeLayou ...
- Java高阶语法---Volatile
背景:听说Volatile Java高阶语法亦是挺进BAT的必经之路. Volatile: volatile同步机制又涉及Java内存模型中的可见性.原子性和有序性,恶补基础一波. 可见性: 可见性简 ...
- 【代码笔记】Web-CSS-CSS 分组和嵌套
一, 效果图. 二,代码. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...
- ABP大型项目实战(1) - 目录
前面我写了<如何用ABP框架快速完成项目>系列文章,讲述了如何用ABP快速完成项目. 然后我收到很多反馈,其中一个被经常问到的问题就是,“看了你的课程,发现ABP的优势是快速开发,那么 ...
- 浅谈OA系统与Portal门户的区别
随着社会信息化的发展与进步,OA办公自动化软件打破了传统复杂的办公方式,使各个行业实现了高效的无纸化办公.由此一来OA快速成长为继财务软件.ERP软件之后的第三大管理软件.随着企业信息化系统的不断增多 ...
- mssql sqlserver获取指定月份当月天数总和
摘要: 下文通过sql函数的形式,获取指定月份的总天数 实验环境:sqlserver 2008 R2 制作思路: 1. 获取指定月份的第一天, 2. 并采用dateadd向后加一个月形成一个新的日期 ...
- Oracle根据符合条件的数据循环批量更新
--批量对符合条件的表记录进行更新 --aa代表查询出的符合条件数据的别名 --aa后的表示需要符合的条件 --loop后开始写更新操作 begin for aa in (select a.objec ...
- rpc接口调用以太坊智能合约
rpc接口调用以太坊智能合约 传送门: 柏链项目学院 在以太坊摸爬滚打有些日子了,也遇到了各种各样的问题.这几天主要研究了一下如何通过rpc接口编译.部署和调用合约.也遇到了一些困难和问题,下面将 ...
- python--继承--方法的重写---和父类的扩展
1.方法的重写 父类的方法不能满足子类的需要,可以对方法重写 具体的实现方式,就相当于在子类中定义了一个和父类同名的方法并实现 重写之后只会对子类的方法调用,而不会调用父类封装的方法 2.对父类方法进 ...