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 ...
随机推荐
- .NET Core整理之配置EFCore
1.新建ASP.NET Core Web应用程序 2.从NuGet下载安装以下工具包 Microsoft.EntityFrameworkCore Microsoft.EntityFrameworkCo ...
- win10安装ubuntu16.04双系统
前话:因为感兴趣吧也是专业需要,所以自学了U盘重装系统以及在win10的情况下安装Ubuntu16.04双系统.借此博客,记录下我安装Ubuntu的过程,方便日后回忆. 正因如此,本篇博客会写的十分简 ...
- Django学习之三:django-admin 和 项目manage.py程序
目录 Django django-admin 和 项目manage.py程序 它俩是什么? 命令程序用法 常用命令 Django django-admin 和 项目manage.py程序 它俩是什么? ...
- Web前端:博客美化:三、右上角的Github Ribbon
1.保存图片到博客园相册 2.复制代码到可以放html代码的地方 我因为数量问题把这段sei到了 页首Html代码 <a href="https://github.com/zhengw ...
- Javascript异步编程之一异步原理
本系列的例子主要针对node.js环境,但浏览器端的原理应该也是类似的. 本人也是Javascript新手,把自己这段时间学习积累的要点总结下来,希望可以对同样在学习Javascript/node.j ...
- 微信小程序(一),授权页面搭建
wxml代码如下: <!--pages/index2/index2.wxml--> <view class="index2Container"> <i ...
- [Web][DreamweaverCS6][高中同学毕业分布去向网站+服务器上挂载]一、安装与破解DreamweaverCS6+基本规划
DreamweaverCS6安装与破解 一.背景介绍:同学毕业分布图项目计划简介 哎哎哎,炸么说呢,对于Web前端设计来说,纯手撕html部分代码实在是难受. 对于想做地图这类的就“必须”用这个老工具 ...
- 【笔记】两个根因分析方法:5WHY&10WHY
什么是问题根因分析 根本原因分析(root cause analysis):通过调查和分析问题哪里出错.为什么出错,寻求防止差错事故再次发生的必要措施,从而提高服务安全和质量. 根因分析目标 问题(发 ...
- Centos 7 安装 ifconfig 管理命令
1. 安装的需求背景 我们知道ifconfig 命令可以用于查看.配置.启用或禁用指定网络接口,如配置网卡的IP地址.掩码.广播地址.网关等,功能不可谓不丰富. 此命令的功能和windows系统的ip ...
- Xamarin移动开发的优点和缺点
在考虑iOS或Android应用程序开发时,我们大多数人会首先考虑Objective-C vs Swift和Java.作为本地技术堆栈,当涉及到iOS和Android应用程序开发时,它们自然是最常用的 ...