暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

JVM——运行时数据区域

算法技术猿 2016-11-26
185

本章围绕下列3个问题来介绍JVM的运行时数据区域:

(1)为什么要了解JVM内存使用情况?

(2)JVM的运行时数据区域有哪些?

(3)在Java中对象访问时如何进行的?

如果不了解JAVA虚拟机是怎样使用内存的,一旦出现内存泄漏和一处方面的问题,那排查错误将会成为一项异常艰难的工作,所以只有了解了JVM内存使用情况后,我们才能更清晰的定位问题。

Java虚拟机运行时数据区域分为5个区:方法区、虚拟机栈、本地方法栈、堆、程序计数器


程序计数器:是一块较小的内存空间,其作用可以看做是当前线程所执行的字节码的行号指示器。字节码解释器工作是就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。分支、循环、跳转、异常处理、线程恢复等基础功能都需要以来这个计数器来完成。程序计数器是线程私有的;

虚拟机栈:它的生命周期与线程相同,其描述的是Java执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧用于存储局部变量表、操作栈、动态链接、方法出口等信息;每个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈。虚拟机栈也是线程私有的

Java虚拟机栈的两种异常StackOverflowError和OutOfMemoryError;

StackOverflowError如果线程请求的栈深度大于虚拟机所允许的深度,将抛出该异常。

OutOfMemoryError如果虚拟机栈可以动态扩展,当扩展时无法申请到足够的内存时会抛出该异常;(当前大部分的虚拟机都支持动态扩展,只不过Java虚拟机规范中也允许固定长度的Java虚拟机栈)

本地方法栈:其作用与虚拟机栈非常相似,区别在于虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到native方法服务。本地方法栈也会抛出StackOverflowError和OutOfMemoryError异常,本地方法栈是线程私有的

Java堆(Heap):是Java虚拟机所管理的内存中最大的一块,是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域唯一的目的是存放对象实例,几乎所有的对象实例以及数组都要在堆上分配内存。Java堆是垃圾收集器管理的主要区域,所以也叫GC堆(俗称垃圾堆,开个玩笑,哈哈哈)。Java堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可,想磁盘空间一样。Java堆在没有足够内存分配时也会抛出OutOfMemoryError异常。

方法区:用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器变异后的代码等数据;方法区是线程共享的内存区域;当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常

运行时常量池:是方法区的一部分,class文件中除了有类的版本、字段、方法、借口等描述信息外,还有一项信息是常量池,用于存放编译器生成的各种字面量和符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。

了解完JVM运行时数据区域后,在探讨对象的访问就容易了很多;所有的对象访问都会涉及Java栈、Java堆、方法区这三个内存区域;例如 Object obj = new Object();Object obj会反映到Java栈的本地变量表中,作为一个reference类型数据出现;new Object()会反映到Java堆中形成一块存储了Object类型的所有实例数据值的结构化内存;在Java堆中还必须包含查找到此对象类型数据的地址信息,这些类型数据则存储在方法区中。主要的对象访问方式有两种:使用句柄和直接指针。


长按下方二维码关注此公众号



文章转载自算法技术猿,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论