欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

轻松get JVM——Java运行时的数据区域

程序员文章站 2022-03-29 17:25:22
Java内存区域的那些事楼房之地基,知晓内存区域,才能知晓JVMJava的内存区域的管理是“全自动”的,每一个刚刚见识的人都会觉得神奇Java的自动管理内存,使得我们不需要操作释放内存的代码,不容易出现内存泄漏与溢出的现象。但是我们不得不提防,一旦出现了内存问题,知晓虚拟机的工作模式,才能排出错误。运行时数据区域这张图很重要,要熟记Java虚拟机在执行Java程序时,将其所管理的内存划分为若干个不同的数据区域,这些区域有各自的用途,以及创建和销毁时间,有的区域,随着虚拟机进程的启动而...

Java内存区域的那些事

楼房之地基,知晓内存区域,才能知晓JVM

Java的内存区域的管理是“全自动”的,每一个刚刚见识的人都会觉得神奇

Java的自动管理内存,使得我们不需要操作释放内存的代码,不容易出现内存泄漏与溢出的现象。

但是我们不得不提防,一旦出现了内存问题,知晓虚拟机的工作模式,才能排出错误。

运行时数据区域

轻松get JVM——Java运行时的数据区域

这张图很重要,要熟记

Java虚拟机在执行Java程序时,将其所管理的内存划分为若干个不同的数据区域,这些区域有各自的用途,以及创建和销毁时间,有的区域,随着虚拟机进程的启动而存在,有的依赖用户线程的启动和结束。

1、程序计数器

程序计数器(Program Counter Register)

一块较小内存空间,是当前线程所执行的字节码行号指示器。字节码解释器工作时通过改变计数器达到语句的切换功能。

“线程私有”,各线程都拥有,互相独立,互不影响。

PC计数器是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域

tips

若为Java方法,计数器记录的是正在执行的虚拟机字节码指令的地址

若为Native方法,这个计算器值为

Native方法为Java的本地方法,Java依赖了很多本地其他语言的代码,这些代码将使用Native注册在Java虚拟机中,供Java使用

2、Java虚拟机栈

Java虚拟机栈(Java Virtual Machine Stacks)

描述Java方法执行的内存模型,每个方法在执行时都会创建一个栈帧(Stack Frame,方法运行时的基础数据结构),存放局部变量表(编译期可知的基础数据类型)、操作数栈、动态链接、方法出口等等信息

线程私有,生命周期与线程相同。

空间以Slot为单位,64位数据占两个。

两个异常:

  • *Error:线程请求深度(方法调用,算术运算会使用)大于虚拟机所允许的深度(编译时指定)。
  • OutOfMemoryError:虚拟机栈在动态扩展时,无法请求到足够的内存

3、本地方法栈

本地方法栈(Native Method Stack)

类似虚拟机栈,为虚拟机使用到的Native方法服务

两个异常:

  • *Error:线程请求深度(方法调用,算术运算会使用)大于虚拟机所允许的深度(编译时指定)。
  • OutOfMemoryError:虚拟机栈在动态扩展时,无法请求到足够的内存

4、Java堆

Java堆(Java Heap)

Java虚拟机所管理的最大块,垃圾收集器管理的主要区域,故也称“GC堆”

存放对象实例,几乎所有的对象实例都在这里分配内存

被所有线程共享

异常

  • OutOfMemoryError:堆中没有内存完成实例分配,并且堆无法再扩展

从垃圾回收的角度,Java堆可以细分为:老年代和新生代。

Java堆可能划分出多个线程私有的分配缓冲区

Java堆可能在不连续的内存空间,但是逻辑上是连续的

5、方法区

方法区(Method Area)

用于存储已被虚拟机加载的类信息常量静态常量即时编译器(JLT,将字节码直接翻译为机器代码,加速执行)编译后的代码等数据

被所有线程共享

Java虚拟机规范将其描述为堆的一个逻辑部分,但有一个别名“非堆”,被多数人称为“永久代

关于字符串常量池,在JDK1.6中,字符串在方法区拥有对象,在JDK1.7中只有引用,在jdk8中,永久代(方法区)被元空间取代了。

https://juejin.im/post/5c160420518825235a05301e

6、运行时常量池

运行时常量池(Runtime Constant Pool),方法区的一部分,

用于存放编译器生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放

除了Class文件中描述的符号引用外,还会把翻译出来的直接引用也存储在运行时常量池中。

动态性:运行期间也能将新变量放入常量池。(如**String类的intren()**方法)

7、直接内存

直接内存(Direct Memory)

虚拟机外的内存

NIO:JDK1.4中新引入,引入一种基于通道(Channel)与缓冲区(Buffer)的I/O方式,可以直接使用Native函数库分配堆外内存,然后通过一个存储在Java堆中DirectByteBuffer对象作为这块内存的引用进行操作。

可能的异常:OutOfMemoryError

本文地址:https://blog.csdn.net/weixin_44494373/article/details/107250982