JVM篇(Java内存区域与内存溢出异常(深入理解JVM第三版))(持续更新迭代)

ops/2024/10/21 5:46:38/

目录

学习前言

一、内存管理控制

1. C/C++程序员

2. Java程序员

二、运行时数据区(深入理解JVM第三版)

1. 程序计数器

2. Java虚拟机栈

3. 本地方法栈

4. Java堆

5. 方法区

运行时常量池


学习前言

JVM学习预热后,我们涉及到了JVM的自动内存管理、类加载机制、字节码这些.

只不过我们只是简单地介绍了下,接下来,就让我们来看看JVM的自动内存管理知识吧,我们肯定

还是先看书吧,以下就是来自于深入理解JVM第三版这一书籍的某章节内容总结!

一、内存管理控制

1. C/C++程序员

每一个对象生命从开始到终结的维护责任由C/C++程序员自己完成,容易出现内存泄漏和内存溢出问题。

2. Java程序员

在虚拟机自动内存管理机制的帮助下,不再需要为每一个new操作去写配对的delete/free代码,正是因为Java程

序员把控制内存的权力交给了Java虚拟机,一旦出现内存泄漏和溢出方面的问题,如果不了解虚拟机是怎样使用内

存的,那排查错误、修正问题将会成为一项异常艰难的工作。

二、运行时数据区(深入理解JVM第三版)

Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域有各自的用途,

以及创建和销毁的时间,有的区域随着虚拟机进程的启动而一直存在,有些区域则是依赖用户线程的启动和结束而

建立和销毁。

Java虚拟机所管理的内存将会包括以下几个运行时数据区域

Java虚拟机运行时数据区

1. 程序计数器

程序计数器(Program Counter Register)就是一块较小的内存空间,它可以看作是当前线程所执行的字节

码的行号指示器。

在Java虚拟机的概念模型中,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节

码指令

它是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。

由于Java虚拟机的多线程是通过线程轮流切换、分配处理器执行时间的方式来实现的,在任何一个确定的时

刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令。

因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器各条线程之间计

数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。

如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;

如果正在执行的是本地(Native)方法,这个计数器值则应为空(Undefined)。

此内存区域没有规定任何OutOfMemoryError情况的区域。

2. Java虚拟机栈

与程序计数器一样,Java虚拟机栈(Java Virtual Machine Stack)也是线程私有的,它的生命周期与线程相

同。虚拟机栈描述的是Java方法执行的线程内存模型

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

栈、动态连接、方法出口等信息。

每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

这块内存区域规定了两类异常状况

  1. 如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;
  2. 如果Java虚拟机栈容量可以动态扩展,当栈扩展时无法申请到足够的内存会抛出OutOfMemoryErro异常。

3. 本地方法栈

本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其区别只是虚拟机栈为虚拟

机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的本地(Native)方法服务。

与虚拟机栈一样,本地方法栈也会在栈深度溢出或者栈扩展失败时分别抛出StackOverflowError和

OutOfMemoryError异常。

4. Java堆

对于Java应用程序来说,Java堆(Java Heap)是虚拟机所管理的内存中最大的一块。

Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。

此内存区域的唯一目的就是存放对象实例,Java世界里“几乎”所有的对象实例都在这里分配内存。

从回收内存的角度看,由于现代垃圾收集器大部分都是基于分代收集理论设计的,所以Java堆中经常会出现

“新生代”“老年代”“永久代”“Eden空间”“From Survivor空间”“To Survivor空间”等名词,说明的是

这些区域划分仅仅是一部分垃圾收集器的共同特性或者说设计风格而已,而非某个Java虚拟机具体实现的固有内存

布局,更不是《Java虚拟机规范》里对Java堆的进一步细致划分。

不少资料上经常写着类似于“Java虚拟机的堆内存分为新生代、老年代、永久代、Eden、Survivor……”这样

的内容。

在十年之前(以G1收集器的出现为分界),作为业界绝对主流的HotSpot虚拟机,它内部的垃圾收集器全部

都基于“经典分代”来设计,需要新生代、老年代收集器搭配才能工作,在这种背景下,上述说法还算是不会产生

太大歧义。

但是到了今天,垃圾收集器技术与十年前已不可同日而语,HotSpot里面也出现了不采用分代设计的新垃圾

收集器,再按照上面的提法就有很多需要商榷的地方了。

从分配内存的角度看,所有线程共享的Java堆中可以划分出多个线程私有的分配缓冲区(Thread Local

Allocation Buffer,TLAB),以提升对象分配时的效率。

不过无论从什么角度,无论如何划分,都不会改变Java堆中存储内容的共性,无论是哪个区域,存储的都只

能是对象的实例,将Java堆细分的目的只是为了更好地回收内存,或者更快地分配内存。

根据《Java虚拟机规范》的规定,Java堆可以处于物理上不连续的内存空间中,但在逻辑上它应该被视为连

续的,这点就像我们用磁盘空间去存储文件一样,并不要求每个文件都连续存放。

但对于大对象(典型的如数组对象),多数虚拟机实现出于实现简单、存储高效的考虑,很可能会要求连续

的内存空间。

Java堆既可以被实现成固定大小的,也可以是可扩展的,不过当前主流的Java虚拟机都是按照可扩展来实现

的(通过参数-Xmx和-Xms设定)。

如果在Java堆中没有内存完成实例分配,并且堆也无法再扩展时,Java虚拟机将会抛出OutOfMemoryError

异常。

5. 方法区

方法区(Method Area)与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类型信

息、常量、静态变量、即时编译器编译后的代码缓存等数据。

在JDK 8以前,把方法区称呼为“永久代”(PermanentGeneration)永久代有-XX:MaxPermSize的上

限,即使不设置也有默认大小,而到了JDK 8,完全废弃了永久代的概念,改用与JRockit、J9一样在本地内存中

实现的元空间Metaspace)来代替,

运行时常量池

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


http://www.ppmy.cn/ops/127192.html

相关文章

小柯:缓解生活压力 戏剧改变人生“免费戏剧训练营”正式启动

10月13日,著名音乐人小柯在社交平台发布了一条视频,称自己要做一件“大事”,而引发广泛关注与热议。在小柯剧场迎来其十二周年之际,为回馈广大观众一直以来的支持与厚爱,特别策划了一场全免费的戏剧训练营活动。凡是年…

vue3 笔记-插槽

结构类似的模块&#xff0c;我们可以考虑用插槽&#xff0c;以便后续复用&#xff1a; 代码&#xff1a; 1.插槽 <script setup> defineProps({title: {required: true,type: String},number: {required: true,type: Number} }) </script><template><d…

Python爬虫进阶:高效数据采集的艺术

在当今数据驱动的世界里&#xff0c;高效的网络爬虫技术已经成为每个数据科学家和后端工程师的必备技能。本文将深入探讨一些高级的Python爬虫技术&#xff0c;这些技术不仅能够大幅提升你的爬虫效率&#xff0c;还能帮助你应对各种复杂的爬虫场景。 1. 异步爬虫&#xff1a;协…

基于Java微信小程序的高校教务管理系统的详细设计和实现(源码+lw+部署文档+讲解等)

详细视频演示 请联系我获取更详细的演示视频 项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更专注于业务逻辑而不…

linux命令之lspci用法

lspci 显示当前主机的所有PCI总线信息 补充说明 lspci命令 用于显示当前主机的所有PCI总线信息&#xff0c;以及所有已连接的PCI设备信息。 语法 lspci(选项)选项 -n&#xff1a;以数字方式显示PCI厂商和设备代码&#xff1b; -t&#xff1a;以树状结构显示PCI设备的层次…

maxkb软件 Windows系统安装教程

文章目录 maxkb介绍安装依赖安装流程maxkb介绍 MaxKB = Max Knowledge Base,是一款基于大语言模型和 RAG 的开源知识库问答系统,广泛应用于企业内部知识库、客户服务、学术研究与教育等场景。 开箱即用:支持直接上传文档 / 自动爬取在线文档,支持文本自动拆分、向量化和 R…

道路垃圾识别数据集 含pt模型界面 18类 共7542张图片,xml和txt标签都有;

道路垃圾识别数据集 含pt模型&界面 18类 共7542张图片&#xff0c;xml和txt标签都有&#xff1b; YOLO道路垃圾识别系统 系统概述 名称&#xff1a;YOLO道路垃圾识别系统 图片数量&#xff1a;7542张标注格式&#xff1a;XML和TXT&#xff08;支持YOLO格式&#xff09;类…

WebServer构建响应 发送响应

1.构建响应 构建响应流程如下 确认方法根据不同方法&#xff0c;以不同方法提参确认访问资源如果用户的URL没有指明要访问的某种资源(路径)&#xff0c;虽然浏览器默认会添加/&#xff0c;但是依旧没有告知服务器&#xff0c;要访问什么资源 此时&#xff0c;默认返回对应服务…