3-JVM 运行时数据区

news2025/1/11 22:50:38

目录

1.堆(线程共享)(最大的一块区域)

2.Java虚拟机栈(线程私有)

3.本地方法栈(线程私有)

4.程序计数器(线程私有)

5.方法区(线程共享)

6.小结

PS:内存布局中的异常问题

①Java堆溢出

②虚拟机栈和本地方法栈溢出


JVM 运行时数据区域也叫内存布局。

但需要注意的是它和 Java 内存模型(Java Memory Model,简称 JMM,是一种读写操作规范)完全不同,属于完全不同的两个概念。

它由以下5 大部分组成:

1.堆(线程共享)(最大的一块区域)

堆的作用:程序中创建的所有对象都保存在堆中。

我们常见的 JVM 参数设置 -Xms10m 最小启动内存是针对堆的,-Xmx10m 最大运行内存也是针对堆的。

【ms 是 memory start 简称,mx 是 memory max 的简称。】

  • -XX:标准参数设置。
  • -X:特定平台参数设置:
  1. -Xms=最小的内存。
  2. -Xmx=最大的内存。

堆里面分为两个区域:新生代和老生代,它们进行垃圾回收的频率、进行垃圾回收使用的策略是不一样的。

  • 新生代放新建的对象。
  • 当经过一定 GC 次数(HotSpot默认GC次数是15次)之后还存活的对象会放入老生代,大文件也会放入老生代。
  • 新生代还有 3 个区域:一个 Endn【占新生代的80%】 + 两个 Survivor(S0/S1)【占新生代的20%,各占10%】。

垃圾回收的时候90%的对象是撑不过JVM第一轮垃圾回收的,会将 Endn 中存活的对象放到一个未使用的 Survivor 中,并把当前的 Endn 和正在使用的 Survivor 清除掉。这样性能很高的。

2.Java虚拟机栈(线程私有)

Java 虚拟机栈的作用:Java 虚拟机栈的生命周期和线程相同。

Java 虚拟机栈描述的是 Java 方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。

常说的堆内存、栈内存中,栈内存指的就是虚拟机栈。

Java 虚拟机栈中包含了以下 4 部分:

  1. 局部变量表: 存放了编译器可知的各种基本数据类型(8大基本数据类型)、对象引用。局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在帧中分配多大的局部变量空间是完全确定的,在执行期间不会改变局部变量表大小。简单来说就是存放方法参数和局部变量。
  2. 操作栈:每个方法会生成一个先进后出的操作栈。
  3. 动态链接:指向运行时常量池的方法引用。【字符串是放在字符串常量池中】
  4. 方法返回地址:PC 寄存器的地址。

什么是线程私有?

由于JVM的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现,因此在任何一个确定的时刻,一个处理器(多核处理器则指的是一个内核)都只会执行一条线程中的指令。

因此为了切换线程后能恢复到正确的执行位置,每条线程都需要独立的程序计数器,各条线程之间计数器互不影响,独立存储。就把类似这类区域称之为"线程私有"的内存。

3.本地方法栈(线程私有)

本地方法栈和虚拟机栈类似,只不过 Java 虚拟机栈是给 JVM 使用的,而本地方法栈是给本地方法【native方法,C++实现的】使用的。

4.程序计数器(线程私有)

程序计数器的作用:用来记录当前线程执行的行号的。

程序计数器是一块比较小的内存空间,可以看做是当前线程所执行的字节码的行号指示器。

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

程序计数器内存区域是唯一一个在JVM规范中没有规定任何OOM情况的区域!

5.方法区(线程共享)

方法区的作用:用来存储被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据的。

在《Java虚拟机规范中》把此区域称之为“方法区”,而在 HotSpot 虚拟机的实现中,在 JDK 7 时此区域叫做永久代(PermGen),JDK 8 中叫做元空间(Metaspace)。

PS:永久代(PermGen)和元空间(Metaspace)是 HotSpot 中对《Java虚拟机规范》中方法区的实现,它们三者之间的关系就好比,对于一辆汽车来说它定义了一个部分叫做“动能提供装置”,但对于不同的汽车有不同的实现技术,比如对于燃油车来说,它的“动能提供装置”的实现技术就是汽油发动机(简称发动机),而对于电动汽车来说,它的“动能提供装置”的实现就是电动发动机(简称电机),发动机和电机就相当于永久代和元空间一样,它是对于“制动器”也就是方法区定义的实现。

JDK 1.8 元空间的变化

  1. 对于 HotSpot 来说,JDK 8 元空间的内存属于本地内存,这样元空间的大小就不受 JVM 最大内存的参数影响了,而是与本地内存的大小有关。
  2. JDK 8 中将字符串常量池移动到了堆中。

运行时常量池

运行时常量池是方法区的一部分,存放字面量与符号引用。

  • 字面量:字符串(JDK 8 移动到堆中) 、final常量、基本数据类型的值。
  • 符号引用:类和结构的完全限定名、字段的名称和描述符、方法的名称和描述符。

6.小结

  • 人为设置参数导致OOM。
  • 内存溢出导致OOM。

PS:内存布局中的异常问题

①Java堆溢出

Java堆用于存储对象实例,只要不断地创建对象,并且保证GC Roots到对象之间有可达路径来避免 GC 清除这些对象,那么在对象数量达到最大堆容量后就会产生内存溢出异常。

可以设置JVM参数-Xms:设置堆的最小值、-Xmx:设置堆最大值。

下面来看一个Java堆OOM的测试:

  • 创建Test类:
import java.util.ArrayList;
import java.util.List;

public class Test {
    static class MyOOMClass {
        public byte[] bytes = null;

        public MyOOMClass() {
            bytes = new byte[1 * 1024 * 1024];
        }
    }
    public static void main(String[] args) {
        List<byte[]> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add(new MyOOMClass().bytes);
            System.out.println("----------i:" + i);
        }
    }
}
  • 运行Test类,出现Test:

  • 设置 Idea 的启动参数:

  • 运行Test类:

由于JDK里还有很多内置的对象,它们会在JVM启动时就加载,也会放在堆中,也会占用一定的空间。

所以实际的程序大小是达不到设置的10mb的。

Java堆内存的OOM异常是实际应用中最常见的内存溢出情况。

当出现Java堆内存溢出时,异常堆栈信息"java.lang.OutOfMemoryError"会进一步提示"Java heap space"。

当出现"Java heap space"则很明确地告知我们,OOM发生在堆上。

此时要对Dump出来的文件进行分析,以MAT为例。分析问题的产生到底是出现了内存泄漏(Memory Leak)还是内存溢出(Memory Overflow) :

  • 内存泄漏:泄漏对象无法被GC。
  • 内存溢出:内存对象确实还应该存活。此时要根据JVM堆参数与物理内存相比较检查是否还应该把JVM 堆内存调大;或者检查对象的生命周期是否过长。

以上是处理Java堆内存的简单方法,处理具体这类问题需要的工具以及知识后面博客会再具体介绍。

  • 去掉参数设置,再次运行:

②虚拟机栈和本地方法栈溢出

由于我们HotSpot虚拟机将虚拟机栈与本地方法栈合二为一,因此对于HotSpot来说,栈容量只需要由Xss参数来设置。

关于虚拟机栈会产生的两种异常:

  1. 如果线程请求的栈深度大于虚拟机所允许的最大深度,会抛出StackOverFlow异常。
  2. 如果虚拟机在拓展栈时无法申请到足够的内存空间,则会抛出OOM异常。
  • 范例一:观察StackOverFlow异常(单线程环境下)
/**
* JVM参数为:-Xss128k 
*
*/
public class Test {
    private int stackLength = 1;
    public void stackLeak() {
        stackLength++;
        stackLeak();
    }

    public static void main(String[] args) {
        Test test = new Test();
        try {
            test.stackLeak();
        } catch (Throwable e) {
            System.out.println("Stack Length: "+test.stackLength);
            throw e;
        }
    }
}

出现StackOverflowError异常时有错误堆栈可以阅读,比较好找到问题所在。

如果使用虚拟机默认参数,栈深度在多数情况下达到1000-2000完全没问题,对于正常的方法调用(包括递归),完全够用。

如果是因为多线程导致的内存溢出问题,在不能减少线程数的情况下,只能减少最大堆和减少栈容量的方式来换取更多线程。

  • 范例二:观察多线程下的内存溢出异常
/**
* JVM参数为:-Xss2M 
* @author 38134
*
*/
public class Test {
    private void dontStop() {
        while(true) {
        }
    }

    public void stackLeakByThread() {
        while(true) {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    dontStop(); 
                }
            });
            thread.start();
        }
    }
 
    public static void main(String[] args) {
        Test test = new Test();
        test.stackLeakByThread();
    }
}

以上代码运行需谨慎,先记得保存手头所有工作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/662837.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Oracle JSON_ARRAYAGG()函数的默认排序问题

引入&#xff1a; 在实际操作中&#xff0c;俺写了这样一个Funtcion&#xff1a; FUNCTION fun_get_xxx(v_param_one VARCHAR2) RETURN CLOB ASv_OUTPUT CLOB;BEGINWITH temp_table AS (SELECT * FROM (( SELECT one.action_id,two.log_timeFROM table_one oneLEFT JOIN table…

Python程序设计基础:字符串

文章目录 一、字符串二、字符串的索引与切片三、字符串处理与操作四、format()格式化方法五、字符串与数值的转换 一、字符串 在Python中&#xff0c;使用单引号或双引号括起来的内容&#xff0c;称为字符串类型数据&#xff08;str&#xff09;&#xff0c;可以使用以下4种方…

Linux主分区,扩展分区,逻辑分区的联系和区别

基本概念 硬盘分区有三种&#xff0c; 主磁盘分区、扩展 磁盘分区、 逻辑分区。 一个 硬盘 主分区至少有1个&#xff0c;最多4个&#xff0c;扩展分区可以没有&#xff0c;最多1个。且 主分区扩展分区总共不能超过4个。 逻辑分区可以有若干个。 在windows下激活的 主分区是 …

树形结构-二叉树结构

树形结构 树形结构简介 树结构是一种非线性储存结构&#xff0c;存储的是具有“一对多”关系的数据元素的集合 树的相关术语 结点&#xff08;Node&#xff09; 使用树结构存储的每一个数据元素被成为“结点” 结点的度&#xff08;Degree of Node&#xff09; 某个结点所拥…

一次完整的Loadrunner基本流程操作

目录 一.生成脚本&#xff1a; 二.回放脚本&#xff1a; 三.创建场景&#xff1a; 四.生成报告&#xff1a; Loadrunner基本流程操作 准备条件&#xff1a; 一.安装loadrunner 二.破解loadrunner &#xff08;注&#xff1a;本次使用lr11版本可以兼容的IE浏览器版本为I…

Qt简单讲解项目结构

Qt简单讲解项目结构 项目结构 主函数入口 #include "mainwindow.h"#include <QApplication>// 程序入口 argc 表示命令行变量的数量 argv表示命令行变量的数组 int main(int argc, char *argv[]) {// a表示应用程序对象QApplication a(argc, argv);MainWin…

绿色节能数据中心供配电系统设计

随着新一代信息技术的快速发展&#xff0c;数据资源存储、计算和应用需求大幅提升&#xff0c;机房在各个领域都有着广泛的应用&#xff0c;如学校内有专用机房、通信类企业有通信机房等。近年来&#xff0c;国家对新型数据中心机房建设也越来越重视&#xff0c;据工信部、国家…

Flutter私服搭建之package查询

温馨提示&#xff1a;这是一篇私有的package客户端查询的平台搭建文章&#xff0c;牵扯到python中的Djiango框架&#xff0c;虽和Flutter相关&#xff0c;但客户端的代码并没有关联&#xff0c;请您根据需要进行阅读。 公有的package&#xff0c;对于一个Flutter开发者而言&…

centos + lnmp + tp6部署的项目,访问的时候经常出现No input file specified

1.检查路径设置 检查你的 Nginx 配置文件是否正确指定了 PHP 路径&#xff0c;确认文件路径是否正确。同时&#xff0c;确保你的 Web 服务器具有访问权限。 server { listen 80; server_name example.com; root /usr/share/nginx/html; index index.html ind…

汽车电子行业ECU烧录工艺人必须面对的重要课题

在汽车电子行业ECU烧录是很一个关键工序&#xff0c;如何有效地通过对它的过程进行管控是每个工艺人必须面对的重要课题。 为了解决烧录过程管控的问题&#xff0c;我们合共软件针对汽车电子行业研发的HG MES中有专门的烧录模块用于应对这一问题。对ECU烧录管控的核心目标是如…

MySQL 数据库的命令操作

文章目录 一.Mysql数据库的基本概念二.Mysql数据库系统发展史三.现主流Mysql数据库介绍四.关系数据库五.非关系数据库介绍六.MySQL安装方法1. 创建新的数据库2.创建新的表3.删除指定的数据库4.删除指定的数据表5.向数据表中插入新的数据记录6.修改、更新数据表中的数据记录7.在…

腾讯云对象存储COS及CDN加速配置

1. 登陆腾讯云官网&#xff0c;进入腾讯云对象存储COS控制台 腾讯云&#xff1a;https://cloud.tencent.com 2. 创建存储空间 3. 添加自定义CDN加速域名 在腾讯云COS的指定的存储桶中添加自定义CDN加速域名 在阿里云官网添加一个解析记录&#xff0c;等待两分钟就可以用该域名…

新书上市丨开启学习自然语言处理与ChatGPT的精彩旅程,你需要这本书!

2022年10月30日&#xff0c;ChatGPT 的横空出世&#xff0c;引起了全球范围内的广泛关注。微软创始人比尔盖茨 (Bill Gates) 认为 “ChatGTP 与互联网具有同等重要的意义”。作为一个人工智能系统&#xff0c;ChatGPT 能准确识别用户意图&#xff0c;与用户进行对话并提供有价值…

postgresql优化案例三:recheck cond

文章目录 1.SQL语句2.查看改善前执行计划:3.解决方案3.1增加work_mem的size3.2.创建合适的索引 4.改善后执行计划 1.SQL语句 delete from sap_dispatchingd_hist awhere exists (select 1 from sap_dispatchingm_hist b where a.ffact_nob.ffact_noand a.fsfc_nob.fsfc_noand …

正确认识:DOTA-CH2-Alkynyl(HCl salt),螯合剂修饰肽,物理化学性质参数

1.试剂基团反应特点&#xff08;Reagent group reaction characteristics&#xff09;&#xff1a; DOTA-CH2-Alkynyl(HCl salt)使用有机溶剂或浓盐酸&#xff08;HCl&#xff09;&#xff0c;在酸化的环境中螯合剂修饰肽的主要优点是高效率和不存在有机溶剂。它可以应用于多种…

给清洁设备以“生命”,国邦从生产型制造走向服务型制造的转型之路|案例研究

国邦协同科技&#xff08;广州&#xff09;有限公司&#xff08;以下简称“国邦”&#xff09;成立于2011年&#xff0c;是行业领先的清洁解决方案服务商&#xff0c;致力于为客户提供全周期清洁解决方案&#xff0c;提高其清洁品质及效率。在2016年到2020年连续5年的时间里&am…

python 操作配置文件。

一&#xff1a;配置文件 1. 什么是配置文件 配置文件是为程序配置参数和初始设置的文件。一般为文本文件&#xff0c;以ini,conf,cnf,cfg,yaml等作为后缀名。 例如mysql的配置文件my.cnf内容如下&#xff1a; [mysqld] # Only allow connections from localhost bind-addre…

Java30天拿下---第三天(选择,循环,二重循环语句,输入,调试,标签)

Java30天拿下---第三天 一 流程图二 选择结构简单的if-else嵌套的if-else多重if的选择语句&#xff08;else-if&#xff09;switch语句 二 输入验证三 程序调试四 循环结构while循环do-while循环for循环流程控制二重循环&#xff08;重点&#xff09; 五 标签 label&#xff08…

中国移动云能力中心捐赠 secScanner 和 ksPack 项目,助力openEuler社区繁荣发展

2023 开放原子全球开源峰会于 6 月 11 日至 13 日在全球数字经济大会期间召开。本届大会以“开源赋能、普惠未来”为主题&#xff0c;全面展示开源技术应用&#xff0c;聚焦全球开源生态最新发展与前沿技术动态。中国移动云能力中心张胜举出席本次大会&#xff0c;并代表移动云…

618仿冒百出,如何保护品牌不受侵害|上云那些事

随着直播带货的兴起&#xff0c;如今的618&#xff0c;更多消费者选择在直播间下单。与传统电商不同的消费体验背后&#xff0c;是消费模式和销售渠道的改变&#xff0c;而与传统电商比较成熟的渠道风控相比&#xff0c;直播间则成为了不法分子潜伏的温床&#xff1a;大量号称“…