JVM调优:JVM运行时数据区详解

news2025/2/22 6:32:27

一、前言

  Java运行时数据区域划分,Java虚拟机在执行Java程序时,将其所管理的内存划分为不同的数据区域,每个区域都有特定的用途和创建销毁的时间。

  其中,有些区域在虚拟机进程启动时就存在,而有些区域则是随着用户线程的启动和结束而建立和销毁。这些数据区域包括程序计数器、虚拟机栈、本地方法栈、堆、方法区等,每个区域都有其自身的特点和作用。

  了解这些数据区域的使用方式和特点,可以更好地理解Java虚拟机的内存管理机制和运行原理。

  JVM的内存模型划分在java1.8与java1.8之前是不一样的,本文将对Java运行时数据区域划分进行详细的介绍,理解清楚了概念之后,才能更好的进行调优分析。

二、运行时数据区域划分

  首先提个概念,经常听人一会提到虚拟机的内存结构,一会又是运行时数据区域划分,其实就是一个意思。因为在《Java虚拟机规范》中用的是【运行时数据区】术语的,并没有内存结构这么一说法。内存结构只是听着更加贴切,更加形象,因此知道内存结构就是运行时数据区的意思就好了。

运行时数据区域划分

1. java1.8之前运行时数据区域划分

在这里插入图片描述
2. java1.8运行时数据区域划分
在这里插入图片描述
在Java中,JVM(Java虚拟机)的运行时数据区主要包括以下几个部分:

①. 程序计数器:

  1. 它是一块很小的内存空间,几乎可以忽略不计,也是运行速度最快的存储区域。

  2. 字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)只会执行一条线程中的指令。

  3. 为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存

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

  5. 它是唯一一个在java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。

②. Java虚拟机栈:

  1. 栈是运行时的单位,即栈解决程序的运行问题,即程序如何执行,或者说如何处理数据。Java 虚拟机栈(Java Virtual Machine Stack),早期也叫 Java 栈。每个线程在创建时都会创建一个虚拟机栈,其内部保存一个个栈帧,对应着一次方法的调用。
  2. Java虚拟机栈是线程私有的,主管Java程序的运行,它保存方法的局部变量(8种基本数据类型,对象的引用地址),部分结果,并参与方法的调用和返回。

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

  2.1 栈帧的内部结构

  1. 局部变量表

    局部变量表是一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量。对于基本数据类型的变量,则直接存储它的值,对于引用类型的变量,则存的是指向对象的引用。

  2. 操作数栈

    栈最典型的一个应用就是用来对表达式求值。在一个线程执行方法的过程中,实际上就是不断执行语句的过程,而归根到底就是进行计算的过程。因此可以这么说,程序中的所有计算过程都是在借助于操作数栈来完成的。

  3. 动态链接

    因为在方法执行的过程中有可能需要用到类中的常量,所以必须要有一个引用指向运行时常量。

  4. 方法返回地址

    当一个方法执行完毕之后,要返回之前调用它的地方,因此在栈帧中必须保存一个方法返回地址。

③. 本地方法栈

  1. 与虚拟机栈所发挥的作用非常相似,它们之间的区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的Native方法服务。本地方法栈也是线程私有的

  2. 允许被实现成固定或者是可动态扩展的内存大小;

  3. 内存溢出方面也是相同的,如果线程请求分配的栈容量超过本地方法栈允许的最大容量抛出 StackOverflowError;

  4. 本地方法是用 C 语言写的;它的具体做法是在Native Method Stack 中登记native方法,在Execution Engine执行时加载本地方法库。

④. Java堆:

  1. Java 堆区在 JVM 启动时的时候即被创建,其空间大小也就确定了,是Java虚拟机所管理的内存中最大的一块。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。

  2. 堆内存的大小是可以调节:例如: -Xms:10m(堆起始大小) -Xmx:30m(堆最大内存大小)。一般情况可以将起始值和最大值设置为一致,这样会减少垃圾回收之后堆内存重新分配大小的次数,提高效率。

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

  4. 所有的线程共享 Java 堆,在这里还可以划分线程私有的缓冲区;

  5. 在方法结束后,堆中的对象不会马上被移除,仅仅在垃圾收集的时候才会被移除。所以堆是 GC(Garbage Collection,垃圾收集器)执行垃圾回收的重点区域。

  了解GC调优方面的知识点,可以参考我的文章 《JVM中常见的垃圾回收算法详解》 《JVM中的垃圾收集器详解》

java8之前与java8的区别主要是下面两个区域

⑤.方法区:
  又称为“永久代”(PermGen space),但在Java 8之后,这个区域被元空间(Metaspace)所替代。它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

  方法区,是一个被线程共享的内存区域。其中主要存储加载的类字节码、class/method/field 等元数据、static final 常量、static 变量、即时编译器编译后的代码等数据。另外,方法区包含了一个特殊的区域“运行时常量池”。

  Java虚拟机规范中明确说明:尽管所有的方法区在逻辑上是属于堆的一部分,但对HotSpotJVM 而言,方法区还有一个别名叫做 Non-Heap(非堆),目的就是要和堆分开。

⑥. 元空间:
  1. 在Java 1.8中,方法区(Method Area)被元空间(Metaspace)所取代。元空间是Java虚拟机规范对方法区的实现方式的一种要求。

  2. 元空间并不在虚拟机中,而是使用本地内存。默认情况下,元空间的大小仅受本地内存限制。

  3. 类元数据放入本地内存,字符串常量池和静态变量放入Java堆中,这样可以加载多少类的元数据就不再由MaxPermSize控制,而由系统的实际可用空间来决定。

三、堆内存模型

  1. java1.8之前堆内存模型
在这里插入图片描述
Young年轻区(代)
  Young区被划分为三部分,Eden区和两个大小严格相同的Survivor区,其中,Survivor区间中,某一时刻只有其中一个是被使用的,另外一个留做垃圾收集时复制对象用,在Eden区间变满的时候,GC就会将存活的对象移到空闲的Survivor区间
中,根据JVM的策略,在经过几次垃圾收集后,任然存活于Survivor的对象将被移动到Tenured区间。

Tenured年老区
  Tenured区主要保存生命周期长的对象,一般是一些老的对象,当一些对象在Young 复制转移一定的次数以后,对象就会被转移到Tenured区,一般如果系统中用了application级别的缓存,缓存中的对象往往会被转移到这一区间。

Perm永久区
  Perm代主要保存class,method,filed对象,这部份的空间一般不会溢出,除非一次性加载了很多的类,不过在涉及到热部署的应用服务器的时候,有时候会遇到java.lang.OutOfMemoryError:PermGenspace的错误,造成这个错误的很大原因就有可能是每次都重新部署,但是重新部署后,类的class没有被卸载掉,这样就造成了大量的class对象保存在了perm中,这种情况下,一般重新启动应用服务器可以解决问题。

Virtual区
  最大内存和初始内存的差值,就是Virtual区

2. java1.8堆内存模型
在这里插入图片描述

  由上图可以看出,jdk1.8的内存模型是由2部分组成,年轻代+年老代。
  年轻代:Eden + 2*Survivor
  年老代:OldGen
  在jdk1.8中变化最大的Perm区,用Metaspace(元数据空间)进行了替换。需要特别说明的是:Metaspace所占用的内存空间不是在虚拟机内部,而是在本地内存空间中,这也是与1.7的永久代最大的区别所在。

为什么要废弃1.7中的永久区?

官网给出了解释:http://openjdk.java.net/jeps/122

This is part of the JRockit and Hotspot convergence effort. 
JRockit customers do not need to configure the permanent generation (since JRockit does not have a permanent generation) 
and are accustomed to not configuring the permanent generation. 

移除永久代是为融合HotSpot JVMJRockit VM而做出的努力,因为JRockit没有永久代,不需要配置永久代。

  现实使用中,由于永久代内存经常不够用或发生内存泄露,出现异常java.lang.OutOfMemoryError:PermGen。基于此,将永久区废弃,而改用元空间,改为了使用本地内存空间。

总结:
  充分理解Java虚拟机(JVM)的运行时数据区(也称为运行时内存区域)是进行JVM调优的基础。JVM的内存管理是其核心功能之一,而理解其内存布局和各个区域的功能,可以帮助我们更有效地进行性能调优。

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

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

相关文章

【数据结构】二叉排序树(查找+插入+删除+效率分析)完整代码+解析

3.1 二叉排序树 3.1.1 定义 二叉排序树的定义 又称二叉查找树&#xff08;BST&#xff0c;Binary Search Tree&#xff09; 二叉排序树是具有以下性质的二叉树&#xff1a; 左子树结点值<根结点值<右子树结点值 进行中序遍历&#xff0c;可以得到一个递增的有序序列。 3…

代码随想录算法训练营Day 38| 动态规划part01 | 理论基础、509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯

代码随想录算法训练营Day 38| 动态规划part01 | 理论基础、509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯 文章目录 代码随想录算法训练营Day 38| 动态规划part01 | 理论基础、509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯理论基础一、常规题目二、解题步骤…

JWT token demo

1、pom依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.9.RELEASE</version> </parent><dependencies><dependency><groupId>…

【JavaWeb】Day74.Spring——AOP进阶(连接点)

连接点 连接点可以简单理解为可以被AOP控制的方法。我们目标对象当中所有的方法不是都是可以被AOP控制的方法。而在SpringAOP当中&#xff0c;连接点又特指方法的执行。 在Spring中用JoinPoint抽象了连接点&#xff0c;用它可以获得方法执行时的相关信息&#xff0c;如目标类名…

【树】简要理解树的概念

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 目录 1、树的概念2、树的相关概念3、结语 1、树的概念 树是一种非线性的数据结构&#xff0c;它…

为什么大家都说it行业要死了?

年后开始找工作开始还不敢投简历怕准备不充分。怕错过了心仪的公司。 花了2周自己死磕了一下自我介绍&#xff0c;和工作经历。然后信心满满就开始投了&#xff0c;结果发现一堆人打招呼一阵欣喜的。可是一查全是外包公司。于是开始了自我怀疑。难道是我能力不行&#xff1f;难…

SQL Server服务启动缓慢或崩溃问题分析

关键词&#xff1a;SQL Server故障解决、服务启动缓慢、服务崩溃、日志文件清理 阅读建议&#xff1a;如果您遇到的是SQL Server服务启动缓慢或无法响应的问题&#xff0c;可以重点阅读文章的第一部分&#xff1b;如果是服务崩溃或重启的问题&#xff0c;可以重点关注第二部分。…

【其他学习参考文档记录】

交叉编译学习参考 nodejs 交叉编译-cliff工作室

经典文献阅读之--D-Map(无需射线投射的高分辨率激光雷达传感器的占据栅格地图)

0. 简介 占用地图是机器人系统中推理环境未知和已知区域的基本组成部分。《Occupancy Grid Mapping without Ray-Casting for High-resolution LiDAR Sensors》介绍了一种高分辨率LiDAR传感器的高效占用地图框架&#xff0c;称为D-Map。该框架引入了三个主要创新来解决占用地图…

UE4_照亮环境_光束light beam

学习笔记&#xff0c;不喜勿喷&#xff0c;侵权立删&#xff01;祝愿生活越来越好&#xff01; 光束&#xff1a;模拟大气中散射的光线。利用定向光源模拟真实曙暮光效果或大气散射的阴影&#xff0c;即可生成 光束 。这些光线为场景添加深度和真实度。 一&#xff1a;一些参数…

(四十一)第 6 章 树和二叉树(包含双亲的树的孩子链表存储)

1. 背景说明 2. 示例代码 1) errorRecord.h // 记录错误宏定义头文件#ifndef ERROR_RECORD_H #define ERROR_RECORD_H#include <stdio.h> #include <string.h> #include <stdint.h>// 从文件路径中提取文件名 #define FILE_NAME(X) strrchr(X, \\) ? strrch…

中学数学研究杂志中学数学研究杂志社中学数学研究编辑部2024年第4期目录

教学纵横 高中数学选择性必修课程函数主线分析 柳双;吴立宝; 1-4 贯彻新课程理念 促学习能力提升——以“三角函数诱导公式”教学为例 陆雨轩; 4-6《中学数学研究》投稿&#xff1a;cn7kantougao163.com 对高中数学新课标教材新增知识点的价值分析 钱伟风;刘瑞美; …

每个开发者都应该拥有的-云服务器!

每个开发者都应该拥有的-云服务器&#xff01; 第一台云服务器ECS言归正传云服务器妙用 每个开发者都该拥有一台云服务器 作为开发者&#xff0c;总是会时不时的跟服务器打交道&#xff0c;不管你是部署应用程序&#xff0c;还是在服务器上面搭建安装基础环境&#xff0c;比如J…

品牌设计理念和logo设计方法

一 品牌设计的目的 设计是为了传播&#xff0c;让传播速度更快&#xff0c;传播效率更高&#xff0c;减少宣传成本 二 什么是好的品牌设计 好的设计是为了让消费者更容易看懂、记住的设计&#xff0c; 从而辅助传播&#xff0c; 即 看得懂、记得住。 1 看得懂 就是让别人看懂…

vue3中使用cherry-markdown

附cherry-markdown官网及api使用示例 官网:https://github.com/Tencent/cherry-markdown/blob/main/README.CN.md api:Cherry Markdown API 考虑到复用性,我在插件的基础上做了二次封装,步骤如下: 1.下载 (一定要指定版本0.8.22,否则会报错: [vitel Internal server e…

AI仿站源码教程

AI仿站源码教程 随着AI技术的不断发展&#xff0c;仿站技术已经越来越成熟&#xff0c;通过AI一键仿站&#xff0c;开发者们可以更快速、更高效地搭建网站。传统的前端开发过程中&#xff0c;需要大量的手工编码和设计&#xff0c;而AI仿站技术可以通过截图或视频&#xff0c;…

RK3568/RK3588智慧校园AI盒子方案,电子班牌,出入口管制,数字化校园等,支持鸿蒙,支持免费定制

智慧校园解决方案基于物联网、人工智能等新兴技术&#xff0c;为师生构建智能化校园环境&#xff0c;涵盖了校园安全、智慧教室、考勤管理、智慧食堂等多个场景&#xff0c;从工作、学习到生活&#xff0c;带来更人性化、更便捷、更高效的服务。 方案架构 方案特点 全面感知校园…

信创应用软件之协同办公(OA)

信创应用软件之协同办公&#xff08;OA&#xff09; 概述 办公 “办公”一词源于历史上对公事、公务处理的简称&#xff0c;现代办公有了更先进的诠释&#xff0c;指在特定时间、特定空间中人互相协作、共同运作的过程&#xff0c; 即围绕以“人”为主的办公主体与其关联的一…

Web APIs 第一天( Dom获取属性操作)

Web API 基本认知 变量声明 1.变量声明有三个 var let 和 constl 我们应该用那个呢&#xff1f;首先var 先排除&#xff0c;老派写法&#xff0c;问题很多&#xff0c;可以淘汰掉…2. let or const ? 建议&#xff1a; const 优先&#xff0c;尽量使用const&#xff0c;原因…

html5的一些新特性

最近总是碰到html5特性这种问题,虽然简单,但是也是自己平时不关注的东西,趁今天时间充裕,那就来总结一下吧 HTML5新特性包括新增了部分标签、表单元素增强、支持视频和音频、支持canvas绘图、提供web存储、提供地理定位功能、提供web workers机制、提供web socket协议、提供CS…