运行时数据区域:
包括 方法区,虚拟机栈,本地方法栈,堆 和程序计数器。
程序计数器:
是一块较小的内存空间,它的作用可以看作是当前线程所执行的字节码的行号指示器。
每一个线程都有自己私有的程序计数器。
如果线程正在执行的是一个JAVA方法,该计数器记录的是正在执行的虚拟机字节码指令的地址,如果正在执行的是native方法,则计数器值为空(undefined)。此内存区域是唯一一个在JAVA虚拟机规范中没有规定任何OutOfMemoryError情况的区域。
JAVA虚拟机栈:
也是线程私有的,生命周期和线程相同。每个方法被执行的时候都会同时创建一个栈帧(stack frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息。每个方法被调用直至执行完成的过程,就对应一个栈帧在虚拟机栈中从入栈道出栈的过程。
这个JAVA虚拟机栈就是我们常说的“栈”。局部变量表存放了元数据类型、引用类型
局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。
在JVM规范中,对这个区域规定了两种异常情况:
- 如果线程请求的栈深度大于JVM允许的深度,抛出StackOverflowError
- 如果虚拟机栈可以动态扩展(目前大部分JVM都可动态扩展),当扩展时无法申请到足够的内存时,会抛出OutOfMemoryError异常
本地方法栈:
与虚拟机栈作用类似,只不过前者是执行JAVA方法服务,而本地方法栈是为Native方法服务。
HotSpot将本地方法栈和虚拟机栈合二为一。
和虚拟机栈一样会抛出来两种异常。
JAVA堆:
JAVA堆是被所有线程共享的一块内存区域,在JVM启动时创建。其作用就是存放对象实例。
JVM规范规定:所有的对象实例及数组都要在堆上分配。
JAVA堆也是垃圾回收管理的主要区域。
由于现在收集器基本采用分代收集算法,所以JAVA堆还可以细分为:新生代和老年代,再细分还有Eden空间、From Survivor空间、To Survivor空间。
根据JVM规范,JAVA堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可,可以是固定大小的,也可以是可扩展的(用-Xmx和-Xms控制),如果堆中没有内存,也无法扩展,抛出OutOfMemoryError。
方法区:
也是所有线程共享的内存区域。它用于存放虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
在JVM规范中被描述为堆的一部分,但却又有一个non-heap的别名。
对于HOTSPOT虚拟机,方法区又被称为永久代(Permanent Generation)
这个区域一样不需要连续的内存,可以选择固定大小或者扩展,还可以选择不实现垃圾回收。确实这个区域的数据一般不参与回收,但这些数据并不一定就是永久存在了,常量池和对类型的卸载也可以成为回收的目标。
抛出OutOfMemoryError
运行时常量池:
是方法区的一部分。
在编译期生成的各种字面量和符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。
这个区域并不是只有编译时产生的常量,也有运行时产生的常量,比如String.intern()方法。
OutOfMemoryError异常
直接内存:
Direct Memory
在JDK1.4中引入了NIO,是一种基于通道与缓冲区的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在JAVA堆里面的DirectByteBuffer对象作为这块内存的引用进行操作。
抛OutOfMemoryError异常
Object obj = new Object();
Object obj反映到JAVA栈的本地变量表中
new Object()反映到JAVA堆中,长度不确定,在JAVA堆中还必须包含能查找到此对象类型数据(如对象类型、父类、实现的接口、方法等)的地址信息,这些类型数据则存放在方法区中。
引用访问对象的方法主流的有两种:
- 使用句柄访问方式,JAVA堆中将会划分出一块内存来作为句柄池,引用对象存储的是对象的句柄地址,而句柄中包含着对象实例数据和类型数据各自的具体地址信息。
- 直接指针访问方式。引用对象中直接存储的就是对象地址。,在堆中的对象又有一个指针指向方法区的对象类型数据。
句柄访问方式最大的好处是在对象被移动时(垃圾回收经常会移动对象),只用改变句柄中的实例数据指针,而引用对象不用修改。
直接指针方式最大的好处是速度更快。HOTSPOT使用这种方式。
设置堆不可扩展,将-Xms和-Xmx参数设置一样即可。
栈溢出
-Xoss参数设置本地方法栈大小(在HOTSPOT虚拟机中,由于本地方法栈和虚拟机栈是一起的,所以这个参数是无效的),-Xss参数设定栈大小。
栈溢出会抛出两种异常stackoverflow和outofmemory,前者表示线程请求的栈深度大于虚拟机所允许的最大深度,后者表示无法申请到足够的内存空间。
实验表明,单线程只会有stackoverflow,不会有outofmemory.但多线程会产生Outofmemory。
这是因为,OS分配给每个进程的内存是有限制的,比如32位windows限制为2GB,栈内存的总量是由2GB减去堆内存(Xmx),再减去方法区容量(MaxPermSize),因为程序计数器消耗内存很小,可以忽略不计。而栈内存又被多个线程所瓜分,这样在线程很多的情况下,内存就可能会耗尽。
运行时常量池溢出
通过String.intern()方法可以向运行时常量池增加内容,该方法会检测常量池中是否有某个字符串,如果有就返回池中的字符串,否则将该字符串加入常量池,再返回该常量池字符串的引用。
由于常量池分配在方法区中,可以通过-XX:PermSize和-XX:MaxPermSize来限制方法区大小。方法区溢出的标志就是OutOfMemoryError: PermGen Space.
方法区溢出
主要是由于动态生成了太多的类造成的,这种溢出的实际场景比如大量JSP或动态生成JSP文件的应用(JSP第一次运行时会需要编译成JAVA类)CGLIB等动态代理生成框架产生的动态类等
本机直接内存溢出
DirectMemory容量可以由-XX:MaxDirectMemorySize指定,如果不指定,则默认与JAVA堆最大值(-Xmx)一样。实际上DirectByteBuffer并没有直接申请分配内存,而是先计算,如果计算得知无足够内存可分配,就抛出异常。
相关推荐
深入理解Java虚拟机学习笔记借鉴.pdf
深入理解Java虚拟机笔记(带目录).docx
自己看《深入理解Java虚拟机》(第二版)所做的一些笔记。因为个人水平有限,能够理解的也只有前面几章的内容,后面的内容觉得看了也不是很理解,就没有记在里面。希望能对大家有所帮助,也希望能和大家一起进步。
NULL 博文链接:https://zhanjia.iteye.com/blog/1842733
包括jvm 的内存模型 对象的创建过程 垃圾回收算法 垃圾回收器 内存分配和回收策略
1. JVM调优 1.1 JVM调优总结(一)-一些概念 1.2 JVM调优总结(二)-一些概念 1.3 JVM调优总结(三)-基本垃圾回收算法 1.4 JVM调优总结(四)-垃圾回收面临的问题 1.5 JVM调优总结(五)-分代垃圾...4.3 深入理解JVM
JVM深入理解Java虚拟机 - 学习笔记
NULL 博文链接:https://zhanjia.iteye.com/blog/1842242
本书十三个章节,分别讲解了android系统基础知识,android系统的结构和核心框架,Java虚拟机和Dalvik虚拟机的知识,实现程序编译和调试,Dalvik的运作流程,DEX优化和安全管理,Android虚拟机生命周期的管理和内存...
它能干什么,文章从作者得角度带大家深入Java虚拟机相关内容,希望对大家有帮助。这里我们使用举例来说明为什么要学习Java虚拟机,其实这个问题就和为什么要学习数据结构和算法是一个道理,工欲善其事,必先利其器。...
深入理解Java虚拟机——JVM高级特性与最佳实践(第2版)
java虚拟机源码学习 Understanding the JVM 深入理解Java虚拟机第三版 (周志明)源码及学习笔记
《深入理解 Java 虚拟机》阅读笔记 本 repo 为《深入理解 Java 虚拟机 第2版》的阅读笔记,并对全书内容按照自己的理解进行了一定程度的整理。《深入理解 Java 虚拟机 第2版》原书主要分为了五个部分,这里仅对前四...
java虚拟机 源码 openjdk7 openjdk7源码(深入理解java虚拟机,读书笔记) 官方源码下载来自:
Linux面试专题及答案+ActiveMQ消息中间件面试专题+Java基础面试题+MySQL性能优化的21个最佳实践+微服务面试专题及答案+深入理解java虚拟机+设计模式面试专题及答案+开源框架面试专题及答案+并发编程及答案+Spring...
《深入理解Java虚拟机》阅读笔记 本repository为《深入理解Java虚拟机 - Jvm高级特性与最佳实践(第三版)》阅读笔记,因为第一章主要讲的是Java的发展历史,这里就不做笔记,直接从第2章的"Java内存区域与内存溢出...
JVMNotesPoweredByMindNode这是在看《深入理解JAVA虚拟机》时用MindNode自己总结的笔记本来想打印出来贴墙上,拿去打印店说这个要打宽2米长4米,50多块,我擦,我都可以买一本书了好吗于是自己用ps切分成40个jpg.......
笔记,1、虚拟机的前世今生,深入理解JVM内存区域1
深入理解java虚拟机:jvm高级特性与最佳实践源码现代操作系统,第 4 版 作者:Andrew S. Tanenbaum, Herbert Bos ** Notes by Henry Cooksley ** 1 介绍 操作系统、外壳、GUI、图形用户界面、内核模式、主管模式、...