java内存区域划分详解

概述:这篇将从概念上介绍Java虚拟机内存的各个区域,讲解这些区域的作用,服务对象以及其中可能产生的问题。

Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途以及创建和销毁时间,称之为运行时数据区域。

运行时数据区主要有程序计数器,Java虚拟机栈,本地方法栈,Java堆,方法区,运行时常量池等部分组成。

针对上面的图文,下面开始开始进入各个部分的详细内容了。

程序计数器,线程私有,由于Java虚拟机的多线程是通过线程流转切换并分配处理器执行时间的方式来实现的,在任意一个确定的时间点,一个处理器都只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,即程序计数器是线程私有的。如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;若线程正在执行的是Native方法,这个计数器的值一般就是undefined。

程序计数器可能出现的异常:此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutofMemory区域的地方,一般遇到OOM问题,不会是这里。

Java虚拟机栈,同样是线程私有的,Java虚拟机栈描述的是Java方法执行的,每个方法在执行的同时都会创建一个栈帧用于存储局部变量表,操作数栈,动态链接,方法出口等信息。每一个方法从调用直至完成的过程,就对应着一个栈帧在虚拟机栈中入栈和出栈的过程。

局部变量表存放了编译期可知的各种数据类型,对象引用和返回地址类型,并且它所需要的内存空间在编译期完成分配,在方法运行期间不会改变局部变量表的大小。

这部分区域可能出现的异常,线程请求的栈深度大于虚拟机所允许的深度,出现StackOverflowError错误,若虚拟机栈可以动态扩展,但在扩展的过程中,无法申请申请到足够的内存会出现OutOfMemoryError错误。

下面我们继续说本地方法栈吧,同样也是线程私有的,这篇文章略长,需要一些耐心,本地方法栈和虚拟机栈的作用类似,区别也只是虚拟机栈为虚拟机执行Java方法服务,本地方法栈则为虚拟机执行Native方法服务。Sun Hotspot直接将本地方法栈和虚拟机栈合二为一。好了,我们说下,这部分区域可能出现的异常StackOverError,OutOfMemoryError错误。

ok,我们继续吧,下面要说的就是最最最最重要的了,Java堆,Java堆属于线程共享的区域,所有的对象实例和数组都要在堆上进行分配,Java堆在虚拟机启动时创建,此内存的唯一目的就是存放对象实例,Java堆可以处于物理上不连续的内存空间,只要逻辑上是连续的即可。

在这块区域内,可能出现的异常,当在堆中没有内存可以完成实例对象的分配时,堆也无法再扩展时,会出现OutOfMemoryError错误信息。

下面说下方法区吧,方法区也是线程共享的,方法区用于存储虚拟机加载的类信息,常量,静态变量,及时编译器JIT编译后的代码等数据,这块区域的内存回收目标主要是针对常量池的回收和对类型的卸载。可能出现的异常,当方法区无法满足内存分配需求时,也同样会出现OutOfMemroyError错误信息。

运行时常量池是方法区的一部分。Class文件中除了有类的版本,字段,方法,接口等描述信息外,还有一项就是常量池,用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。一般来说,除了保存Class文件中的符号引用外,还会把翻译出来的直接引用也存储在运行时常量池中。运行时常量池相对于Class文件常量池的另外一个重要特征是具备动态性,即运行期间也可能将新的常量放入池中,String类的itern()方法,此区域可能出现的异常,当常量池无法再申请到内存时会跑出OutOfMemoryError错误。

由于直接内存不属于Java虚拟机运行时数据区的一部分,也不是虚拟机规范中定义的内存区域,JDK1.4中新加入了NIO类,引入了一种基于通道与缓冲区的I/O方式,它可以使用Native函数库直接分配对外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作,避免了在Java堆和Native中来回复制数据,在一些场景中显著提高性能。

直接内存的分配不会受到Java堆大小的限制,但是,既然是内存,肯定会受到本机总内存大小和处理器寻址空间的限制。

在这说明一下,以上说的内容会有一点和jdk8不太一样,因为jdk8多了元空间的概念,自己没有在这里进行说下,说的虚拟机针对于主流的虚拟机hotSpot,ok接着十一那篇文章,这篇文章也详细介绍了每个区域都是干啥的,都会出现什么异常。

原文发布于微信公众号 - 后端Coder(gh_245290c1861a)

原文发表时间:2019-10-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券