理解JAVA虚拟机(一)内存区域

本文介绍了Java虚拟机内存管理的各个区域,包括程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区等,详细解释了各区域的作用、特点及可能出现的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  本系列是周志明老师《深入理解Java虚拟机》第三版的学习笔记。

  Java应用运行时内存交给Java虚拟机自动管理,但出现内存泄漏和溢出问题时,如果不了解虚拟机是怎样使用内存的,那排查错误、修正问题将会成为一项异常艰难的工作。

  下面从概念上介绍Java虚拟机内存的各个区域,讲解这些区域的作用、服务对象以及可能产生的问题,这也是学习内存管理的第一步。

  Java虚拟机内存区域图示:

在这里插入图片描述

一、 程序计数器

  多线程是通过线程轮流切换,分配处理器执行时间的方式来实现。为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器。

  • 属于线程私有的内存区域。

  • Java虚拟机唯一不会产生OutOfMemoryError异常的区域。

二、Java虚拟机栈

  每个方法被执行的时候,Java虚拟机都会同步创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态连接、方法出口等信息。

  • 属于线程私有的内存区域。

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

  • 如果申请内存时失败,抛出OutOfMemoryError异常。

  • 如果Java虚拟机栈容量可以动态扩展,当栈扩展时无法申请到足够的内存会抛出OutOfMemoryError异常。(HotSpot的虚拟机栈不能动态扩展)。

三、本地方法栈

  与虚拟机栈的作用类似,区别:虚拟机栈为虚拟机执行Java方法(也就是字节码)服务。本地方法栈则为虚拟机使用到的本地(native)方法服务。

  • 属于线程私有的内存区域。

  • 《Java虚拟机规范》未对本地方法栈中使用的语言、使用方式与数据结构未做任何强制规定。HotSpot虚拟机直接将本地方法栈和虚拟机栈合二为一。

  • 本地方法栈抛出的异常与虚拟机栈一致。

四、Java堆

  Java堆(Java Heap)是在虚拟机启动时创建,此内存区域的唯一目的就是存放对象实例。

  • 所有线程共享的一块内存区域。

  • 基于分代设计的垃圾收集器,会将堆内存分为新生代、老年代、永生代等等。

  • Java堆可扩展,通过参数-Xmx和-Xms设定。

  • 如果在Java堆中没有内存完成实例分配,并且堆也无法再扩展时,会抛出OutOfMemoryError异常。

五、方法区

  方法区(Method Area)用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。

  • 与Java堆一样,是各个线程共享的内存区域。

  • JDK8中,方法区放弃永久代的概念实现,用本地内存中实现的元空间(Metaspace)来代替。

  • 方法区无法满足新的内存分配需求时,将抛出OutOfMemoryError异常。

六、运行时常量池

  运行时常量池(Runtime Constant Pool)是方法区的一部分。Class文件中除了有类的版本、字段、接口等描述信息外,还有一项信息是常量池表(Constant Pool Table),用于存放编译期生成的各种字面量与符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。

  • 动态性,并非预置入Class文件中常量池的内容才能进入方法区运行时常量池,运行期间也可以将新的常量放入池中,比如String类的intern()方法。

  • 受方法区内存的限制,无法申请到内存时抛出OutOfMemoryError异常。

七、直接内存

  直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,也不是《Java虚拟机规范》中 定义的内存区域。但是这部分内存也被频繁地使用,而且也可能导致OutOfMemoryError异常出现,所以我们放到这里一起讲解。

  • JDK1.4中新加入了NIO(New Input/Output)类,引入了一种基于通道与缓冲区的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在Java堆和Native堆中来回复制数据。

  • 本机直接内存的分配不会受到Java堆大小的限制,但受到本机总内存限制,设置-Xmx等参数信息时,容易忽略掉直接内存,使得出现OutOfMemoryError异常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值