本文分为两部分:一是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内存区域详解的更多相关文章

  1. JVM内存区域详解(Eden Space、Survivor Space、Old Gen、Code Cache和Perm Gen)

    JVM区域总体分两类,heap区和非heap区.heap区又分为: Eden Space(伊甸园). Survivor Space(幸存者区). Old Gen(老年代). 非heap区又分: Cod ...

  2. JVM 内存溢出详解(栈溢出,堆溢出,持久代溢出、无法创建本地线程)

    出处:  http://www.jianshu.com/p/cd705f88cf2a 1.内存溢出和内存泄漏的区别 内存溢出 (Out Of Memory):是指程序在申请内存时,没有足够的内存空间供 ...

  3. Java(JVM运行时)各种内存区域详解及扩展

    本文整理于  Java内存与垃圾回收调优 Java 堆内存 从几个sample来学习Java堆,方法区,Java栈和本地方法栈 首先来一张图让我们理清楚java运行时状态: 诚然,如上图所示:java ...

  4. JVM虚拟机20:内存区域详解(Eden Space、Survivor Space、Old Gen、Code Cache和Perm Gen)

    1.内存区域划分 根据我们之前介绍的垃圾收集算法,限定商用虚拟机基本都采用分代收集算法进行垃圾回收.根据对象的生命周期的不同将内存划分为几块,然后根据各块的特点采用最适当的收集算法.大批对象死去.少量 ...

  5. JVM内存结构详解

    从java编程语言说起... 1. Java编程语言简介 1.1 编程语言概述 系统级和应用级 系统级:C,C++,go,erlang 应用级:C#,Java,Python,Perl,Ruby,php ...

  6. JVM内存配置详解

    前段时间在一个项目的性能测试中又发生了一次OOM(Out of swap sapce),情形和以前网店版的那次差不多,比上次更奇怪的是,此次搞了几天之后啥都没调整系统就自动好了,死活没法再重现之前的O ...

  7. jvm内存GC详解

    一.相关概念  a. 基本回收算法 1. 引用计数(Reference Counting)  比较古老的回收算法.原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数.垃圾回收时,只用收 ...

  8. JVM内存配置详解(转)

    前段时间在一个项目的性能测试中又发生了一次OOM(Out of swap sapce),情形和以前网店版的那次差不多,比上次更奇怪的是,此次搞了几天之后啥都没调整系统就自动好了,死活没法再重现之前的O ...

  9. JVM内存参数详解以及配置调优

    基本概念:PermGen space:全称是Permanent Generation space.就是说是永久保存的区域,用于存放Class和Meta信息,Class在被Load的时候被放入该区域He ...

随机推荐

  1. 持续集成配置之Nuget

    持续集成配置之Nuget Intro 本文是基于微软的 VSTS(Visual Studio Team Service) 做实现公众类库的自动打包及发布. 之前自己的项目有通过 Github 上的 T ...

  2. 微服务定义及.Net Core中用的技术

    微服务 定义: 它是一种架构模式,提倡将大的单体系统,按业务拆分成一个个较小且独立的服务,服务与服务之前进行相互协作和配合. 历史: 针对互联网行业的蓬勃发展,需要支撑的业务越来越多,越来越大,单体程 ...

  3. Java开发笔记(六十)匿名内部类的优势

    前面依次介绍了简单接口和扩展接口,给出的范例都是自定义的接口代码,其实Java系统本身就自带了若干行为接口,为了更好地理解系统接口的详细用法,接下来还是从一个基础的例子出发,抽丝剥茧地逐步说明接口的几 ...

  4. OPC协议解析-OPC UA OPC统一架构

    1    什么是OPC UA 为了应对标准化和跨平台的趋势,为了更好的推广OPC,OPC基金会近些年在之前OPC成功应用的基础上推出了一个新的OPC标准-OPC UA.OPC UA接口协议包含了之前的 ...

  5. Vysor Pro破解助手

    Vysor更新到1.7.7版本后,原来提供的VysorPro助手无法正常破解了. 针对新版本的改动,更新了一下Vysor破解助手,支持破解Vysor 1.6.6和Vysor1.7.7之间的版本. Vy ...

  6. Lua在Redis中的应用

    转载至笑松小站http://blog.seoui.com/2018/01/27/redis-lua/ redis从2.6版本开始内置支持Lua解释器,解释器提供了3个函数来处理redis的命令redi ...

  7. shell脚本批量ssh登陆主机并执行命令

    shell脚本批量ssh登陆主机并执行命令 今天在客户现场遇到了这个问题,客户没有管理工具,无法批量登陆主机下发命令,几个个C段啊,让我一个一个登陆,.................. 所以写了个s ...

  8. sql order by和case THEN 并用

    今天在工作中遇到一个多表查询,并且按精准度匹配排序的一个需求,费了我好大劲在此和大家分享一些心得 开始我是想根据他的搜索字段的长度来排序,但是遇到图二的这种结果就不好排序了 order by abs( ...

  9. .net DLL版本管理

    每个DLL打上版本号,方便识别维护

  10. 启动期间的内存管理之pagging_init初始化分页机制--Linux内存管理(十四)

    1 今日内容(分页机制初始化) 在初始化内存的结点和内存区域之前, 内核先通过pagging_init初始化了内核的分页机制. 在分页机制完成后, 才会开始初始化系统的内存数据结构(包括内存节点数据和 ...