JVM-Java内存区域
JVM虚拟机运行时数据区结构分为:

其中方法区和堆是所有线程共享的内存区域,而Java栈、本地方法栈、程序计数器是线程私有的。
我们详细介绍运行时数据区的各个区域及其作用。
程序计数器:
一块较小的内存空间,字节码指示器工作时通过改变计数器的值来选取下一条需要执行的字节码指令。分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。
JVM的多线程通过线程轮流切换并分配处理器执行时间的方式来实现,在任何一个确定的时刻,一个处理器都只会执行一条线程中的指令,为了保证线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间的计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。
存储内容:
当线程执行一个Java方法时,计数器记录的是正在执行的JVM字节码指令的地址。如果执行的是Native方法,计数器则为空(Undefined)。
该内存区域是唯一一个在jvm规范中没有规定任何OutOfMemoryError情况的区域。
Java虚拟机栈:
线程私有,生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
存储内容:
栈的存储可以说是局部变量表部分,存放了编译期可知的基本数据类型(boolean、byte、char、short、int、float、long、double),对象引用(reference类型,它不等同于对象本身,根据不同的虚拟机实现,它可能是一个指向对象起始地址的引用指针,也可能指向一个代表对象的句柄或者其他与此对象相关的位置)和returnAddress类型(指向了一条字节码指令的地址)。局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。
异常状况:
1、线程请求的栈深度大于JVM所允许的深度,抛出StackOverflowError异常。
2、虚拟机栈可以动态扩展时,当无法申请到足够的内存,就会抛出OutOfMemoryError异常。
本地方法栈:
作用与虚拟机栈非常相似,区别在于虚拟机栈服务于执行Java方法,而本地方法栈服务于执行Native方法。它也会抛出StackOverflowError和OutOfMemoryError异常
Java堆:
Java虚拟机管理的内存中最大的一块,被所有线程共享的内存区域。虚拟机启动时创建,该区域的目的就是存放对象实例,几乎所有对象实例都在这里分配内存。Java堆也是垃圾收集器管理的主要区域,又被称为GC堆。
从收集器的分代收集法来看,Java堆还可以分为:新生代和老年代。Java堆可以处于物理上不连续的内存空间,只要逻辑上是连续的即可。
存储内容:
几乎所有对象实例
异常情况:
如果在堆中没有内存完成实例分配,并且堆无法再扩展时,将抛出OutOfMemoryError异常。
方法区:
与Java堆一样,是各个线程共享的内存区域。别名非堆(Non-Heap),目的是与Java对区分开
存储内存:
存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
Java虚拟机规范对这块区域限制非常宽松,除了和Java堆一样不需要连续的内存和可以选择固定大小或者可扩展外,还可以选择不实现垃圾收集。因此又有很多人将其趁为永久代。这个区域内存回收目标主要是针对常量池的回收和对类型的卸载,一般来说这个区域的回收“成绩”比较难以令人满意,尤其是类型的卸载,条件相当苛刻,但是这部分区域的回收确实是有必要的。
异常情况:
当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常。
方法区有时候也被称为持久代(PermGen),所有对象在实例化后的整个运行周期内,都被存放在堆内存中。堆内存又被划分成不同的部分:伊甸区(Eden),幸存者区域(Survivor Sapce),老年代(Old Generation Space)。
方法的执行都是伴随着线程的。原始类型的本地变量以及引用都存放在线程栈中。而引用关联的对象比如String,都存在在堆中。
运行时常量池(Runtime Constant Pool):
方法区的一部分,存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中释放。
当常量池无法再申请到内存时会抛出OutOfMemoryError异常。
直接内存:
该区域并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域,但这部分内存被频繁使用也可能导致OutOfMemoryError异常。
本机直接内存分配不会受到Java堆大小的限制,但会受到本机总内存及处理器寻址空间的限制。配置虚拟机参数时,忽略直接内存,会使得各个内存区域总和大于物理内存限制,导致动态扩展时出现OutOfMemoryError异常。
OutOfMemoryErrors:
Exception in thread “main”: java.lang.OutOfMemoryError: Java heap space 原因:对象不能被分配到堆内存中 Exception in thread “main”: java.lang.OutOfMemoryError: PermGen space 原因:类或者方法不能被加载到持久代。它可能出现在一个程序加载很多类的时候,比如引用了很多第三方的库; Exception in thread “main”: java.lang.OutOfMemoryError: Requested array size exceeds VM limit 原因:创建的数组大于堆内存的空间 Exception in thread “main”: java.lang.OutOfMemoryError: request <size> bytes for <reason>. Out of swap space? 原因:分配本地分配失败。JNI、本地库或者Java虚拟机都会从本地堆中分配内存空间。 Exception in thread “main”: java.lang.OutOfMemoryError: <reason> <stack trace>(Native method) 原因:同样是本地方法内存分配失败,只不过是JNI或者本地方法或者Java虚拟机发现
参考资料:
《深入理解Java虚拟机——JVM高级特性与最佳实践(第2版)》
《纯洁的微信-JVM系列文章》:http://www.ityouknow.com/jvm.html
由衷的感谢提供学习资料的前辈们!!!
JVM-Java内存区域的更多相关文章
- JVM Java 内存区域透彻分析(转)
出处: Java 内存区域透彻分析 Java8内存模型—永久代(PermGen)和元空间(Metaspace) 这篇文章主要介绍Java内存区域,也是作为Java虚拟机的一些最基本的知识,理解了这 ...
- 一、JVM — Java内存区域
Java 内存区域详解 写在前面 (常见面试题) 基本问题 拓展问题 一 概述 二 运行时数据区域 2.1 程序计数器 2.2 Java 虚拟机栈 2.3 本地方法栈 2.4 堆 2.5 方法区 2. ...
- 深入理解JVM - Java内存区域与内存溢出异常 - 第二章
一 运行时数据区域 JVM在执行Java程序的过程中会把它管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间. 程序计数器 程序计数器(Program Counter ...
- JVM java内存区域的介绍
jvm虚拟机在运行时需要用到的内存区域.广泛一点就是堆和栈,其实不然,堆和栈只是相对比较笼统的说法,真正区分有如下几个 先上图一: 总的就是 java的内存模型 内存模型又分堆内存(heap)和方法区 ...
- JVM——Java内存区域
一,概述: Java跟C++不同,在内存管理区域C++程序员拥有着最高权力,但是正是因为如此,所以C++程序员要照顾这个对象的生老病死,从创建到消亡都是由程序员决定的. 但是Java程序员在虚拟机的自 ...
- java虚拟机学习-JVM内存管理:深入Java内存区域与OOM(3)
概述 Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 对于从事C.C++程序开发的开发人员来说,在内存管理领域,他们即是拥有最高权力的皇帝又 ...
- JVM参数配置 java内存区域
java内存区域 一些基本概念 http://www.importnew.com/18694.html https://www.cnblogs.com/wangyayun/p/6557851.html ...
- Java内存管理:Java内存区域 JVM运行时数据区
转自:https://blog.csdn.net/tjiyu/article/details/53915869 下面我们详细了解Java内存区域:先说明JVM规范定义的JVM运行时分配的数据区有哪些, ...
- JVM系列1:Java内存区域
JVM系列主要分享自己都虚拟机的理解,我自学时的知识框架多来源于<深入理解Java虚拟机_JVM高级特性与最佳实践>这本书,感兴趣的朋友可直接去阅读这本书. 本系列暂定有3部分,它们是学习 ...
- JVM自动内存管理机制——Java内存区域(下)
一.虚拟机参数配置 在上一篇<Java自动内存管理机制——Java内存区域(上)>中介绍了有关的基础知识,这一篇主要是通过一些示例来了解有关虚拟机参数的配置. 1.Java堆参数设置 a) ...
随机推荐
- Java synchronized解析
多线程三大特性: 可见性.原子性.有序性 synchronize的特性: 1.同一时刻只有一个线程访问临界资源 2.其它未获取到锁执行权的线程必须排队等待 3.保证共享资源的原子性.可见性和有序性 4 ...
- C#:获取视频某一帧的缩略图
读取方式:使用ffmpeg读取,所以需要先下载ffmpeg.网上资源有很多. 原理是通过ffmpeg执行一条命令获取视频某一帧的缩略图. 首先,需要获取视频的帧高度和帧宽度,这样获取的缩略图才不会变形 ...
- 本机mysql 5.7服务启动后停止,某些服务在未有其他应用程序使用时停止
本机mysql 5.7服务启动后停止,某些服务在未有其他应用程序使用时停止 出现这种报错,mysql服务启动不了: 错误的尝试: 1:尝试了这个博客:https://blog.csdn.net/wai ...
- (其他)window10分盘
由于thinkpad的一个c盘大概是一个t左右,所以我们先分一下盘. 首先找到计算机管理,然后找磁盘管理,右击比较大的磁盘,压缩卷,大概就压缩一半吧,然后新建简单卷,一直下一步,紧接着就完成了. ...
- javascript的隐式类型转换
首先简单了解js的typeof,会返回六种类型 即 number string boolen function object undefined 也就是六种基本数据类型 显示类型转换大概有以下几种: ...
- springmvc复习笔记----文件上传multipartResolver
结构 web.xml <?xml version="1.0" encoding=&q ...
- C语音输出前100个回文素数,每行10个,适当对齐
#include<stdio.h> #include<math.h> int ss(long n) { ); ) ; ;i<=sqrt(n);i++) ); ; } lo ...
- C#核心基础--浅谈类和对象的概念
浅谈类和对象的概念 一.什么是类?什么是对象? 学习一门面向对象编程语言,我们必须得知道什么是类?什么是对象? 类(Class)实际上是对某种类型的对象定义变量和方法的原型.它表示对现实生活中一类具有 ...
- SQL SERVER 查询表字段中是否有汉字
SELECT * FROM TB WHERE COL LIKE N'%[吖-咗]%'
- ajax调用WebService实现数据库操作
首先说下测试环境和思路: 前端收集数据转换成json格式传输到后端,处理并存入数据库 1.数据库操作: [WebMethod] public string InsertPoint(string dat ...