关于JVM内存模型和堆内存模型的理解

文章目录

  • 前言
  • 一、JVM 内存模型的理解
    • 1.第一部分:线程共享区(堆和方法区)
    • 2.第二部分:线程独占区(程序计数器、虚拟机栈和本地方法栈)
    • 3.JVM的几个知识点
      • 3.1 垃圾回收就指线程共享区(堆和方法区)的回收?
      • 3.2 JVM的内存分配算法有哪些?
      • 3.3 JVM优化技术有哪些?
      • 3.4 JVM用于提高对象分配效率的技术有哪些?
  • 二、堆内存模型的理解


前言

理解 JVM 内存模型和堆内存模型是 Java 开发中的重要知识点,也经常会在面试中被问及。下面结合示意图,记录对这两个知识点的理解。

一、JVM 内存模型的理解

JVM内存模型可理解为2部分5大块,如下图所示:
在这里插入图片描述

1.第一部分:线程共享区(堆和方法区)

1.1 Heap
Heap用来保存对象实例的属性值,并不保存对象的方法(以帧栈的形式存在JVM Stack中),对象实例在Heap中分配好以后,需要在Stack中保留4字节的Heap内存地址,用来定位该对象实例在Heap中的位置。(元空间替换永久代后,方法区的字符串常量池和一般变量也保存在Heap中)

1.2 Method Area
方法区是一个JVM的概念,元空间( Metaspace)是方法区的具体实现
JDK1.8后的方法区的实现由永久代替换为元空间,其与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制,但可以通过以下参数来指定元空间的大小,有两个参数:-XX:MetaspaceSize=N和 -XX:MaxMetaspaceSize=N,对于64位JVM来说,元空间的默认初始大小是20.75MB,默认的元空间的最大值是无限。MaxMetaspaceSize用于设置metaspace区域的最大值,这个值可以通过mxbean中的MemoryPoolBean获取到,如果这个参数没有设置,那么就是通过mxbean拿到的最大值是-1,表示无穷大。
方法区内有个非常重要的区域-运行时常量池(Runtime Constant Pool,简称RCP)。类的版本、字段、方法、接口等信息保存在运行时常量池中。

2.第二部分:线程独占区(程序计数器、虚拟机栈和本地方法栈)

2.1 程序计数器
程序计数器用来记录程序的跳转。

2.2 虚拟机栈(栈内存)
Java方法执行的内存模型:每个方法执行的同时会创建一个栈帧。栈帧是用于支持虚拟机进行方法调用和方法执行的数据结构。栈帧存储了方法的局部变量表、操作数栈、动态连接和方法返回地址等信息。每一个方法从调用开始至执行完成的过程,都对应着一个栈帧在虚拟机里面从入栈到出栈的过程。如下图所示
在这里插入图片描述

2.3 Native Method Stack
与VM Stack相似,VM Stack是为JVM提供执行JAVA方法的服务,Native Method Stack是为JVM提供执行native方法的服务。

3.JVM的几个知识点

3.1 垃圾回收就指线程共享区(堆和方法区)的回收?

JVM初始化运行的时候,都会分配好线程共享区和线程独占区,当线程终止时,线程独占区的三块(虚拟机栈,本地方法栈和程序计数器)所占用的内存空间也会被及时释放掉。因为线程独占区的生命周期与所属线程相同,而线程共享区的生命周期与JAVA程序运行的生命周期相同,这就是系统垃圾回收的场所只发生在线程共享区的原因(实际上对大部分虚拟机来说只发生在Heap上)

3.2 JVM的内存分配算法有哪些?

两种方式是指针碰撞(Pointer Bumping)和空闲列表(FreeList)。
类加载检查通过后,虚拟机为新生对象分配内存。为对象分配空间的任务等同于把一块确定大小的内存从java堆中划分出来。Java堆中内存是否绝对规整,决定了采用的内存分配算法(Java堆是否规整是由所采用的垃圾收集器是否带有压缩功能决定, 因此,在使用Serial、ParNew等带Compact过程的收集器时,系统采用的分配算法是指针碰撞,而使用CMS这种基于Mark-Sweep算法的收集器时,通常采用空闲列表
3.2.1 堆内存绝对规整的情况,已使用内存和空闲的内存分两部分存放,中间有一个指针作为分界点指示器,分配内存时,就是把指针向空闲的那边挪到一段与对象大小相等的距离,这种方式称为-指针碰撞,如下图
在这里插入图片描述
3.2.2 堆内存不规整的情况,已使用内存和空闲的内存相互交错,没办法采用指针碰撞,虚拟机必须维护一个列表,记录哪些内存块是可用的,分配时,从列表中将一块足够大的空间划分给对象,并更新列表记录,这种方式称为-空闲列表,如下图
在这里插入图片描述

3.3 JVM优化技术有哪些?

即时编译器(Just-In-Time Compiler,JIT): JIT 编译器是 Java 虚拟机的核心组件之一,负责将 Java 字节码动态编译成本地机器码,以提高程序的执行效率。JIT 编译器可以根据程序的运行情况进行优化,包括方法内联、循环展开、逃逸分析等技术,从而使得程序在运行时达到更高的性能。

逃逸分析(Escape Analysis): 逃逸分析用于确定对象的动态作用域,从而优化内存分配和对象的生命周期。逃逸分析可以实现栈上分配、同步消除、标量替换等优化,减少对象在堆上的分配和访问开销,提高程序的性能和内存利用率。

垃圾回收(Garbage Collection): 垃圾回收是 Java 虚拟机管理内存的重要机制,负责自动回收不再使用的对象,并释放其占用的内存空间。优化垃圾回收算法和调优垃圾回收器参数可以降低垃圾回收的停顿时间、减少内存碎片化,并提高系统的吞吐量和响应速度。

类加载优化: 类加载是 Java 虚拟机启动时必不可少的过程,优化类加载可以加速程序的启动速度和减少内存占用。类加载优化包括延迟加载、预加载、类缓存、类预编译等技术,可以根据应用的特性和需求来选择合适的优化策略。

锁优化: 锁是多线程编程中常用的同步机制,但不正确的锁使用会导致性能问题和死锁等并发问题。优化锁的使用包括锁粗化、锁消除、锁重偏向等技术,可以减少锁的竞争和粒度,提高程序的并发性能。

字符串优化: 字符串是 Java 程序中常用的数据类型,但频繁的字符串操作会带来性能和内存消耗的问题。优化字符串的使用包括字符串常量池、字符串拼接优化、字符串替换等技术,可以降低字符串操作的开销,提高程序的性能和内存利用率。

编译器优化: 除了 JIT 编译器外,Java 虚拟机还包括一些静态编译器和即时编译器,用于对 Java 代码进行优化和转换。编译器优化包括代码优化、指令优化、内联优化等技术,可以提高程序的执行效率和运行速度。

3.4 JVM用于提高对象分配效率的技术有哪些?

对象池(Object Pool): 对象池是一种将对象预先创建并缓存起来,以便在需要时可以直接重用的技术。通过对象池,可以减少对象的频繁创建和销毁,从而提高对象的重用率和系统的性能。

栈上分配(Stack Allocation): 栈上分配是一种将对象分配在线程栈上而不是堆上的技术。栈上分配可以提高对象的访问速度,减少垃圾回收的压力,但是由于线程栈的大小有限,只适用于一些较小的对象。

TLAB优化(TLAB Optimization): 除了基本的TLAB机制外,Java虚拟机还对TLAB进行了一些优化,例如根据应用程序的运行情况动态调整TLAB的大小、TLAB的并发分配等,以进一步提高对象分配的效率。

标量替换(Scalar Replacement): 标量替换是一种将对象拆分为其成员变量(标量)并分别进行优化的技术。通过标量替换,可以将对象的成员变量分配在栈上或者寄存器中,以减少对象的内存消耗和访问延迟。

对象内联(Object Inlining): 对象内联是一种将小对象的字段直接内联到使用该对象的地方的优化技术。通过对象内联,可以减少对对象的创建和访问,提高程序的性能。

逃逸分析(Escape Analysis): 逃逸分析是一种分析对象在方法中的生命周期和作用域的技术。通过逃逸分析,可以判断对象是否会逃逸到方法外部,从而决定是否可以进行一些优化,如栈上分配、标量替换等。

二、堆内存模型的理解

Java堆是JVM最大的一块内存空间,被划分成两个不同区域:新生代和老年代,新生代又被划分为三个区域:Eden、From Survivor、To Survivor。划分的目的是为了JVM能够更好的管理堆内存中的对象,包括内存分配及内存回收。图示如下:
在这里插入图片描述
新生代-Young Generation,主要用来存放新生的对象;
老年代-Old Generation,主要存放应用程序生命周期长的内存对象;
堆大小=新生代+老年代,堆大小可以通过参数-Xms、-Xmx来指定。
默认的新生代和老年代的比例值为1:2,其中,新生代被细分为Eden和Survivor区域, 这两个 Survivor 区域分别被命名为 from 和 to,以示区分。
默认的Eden:from:to=8:1:1,JVM每次只使用Eden和其中一块Survivor区域来为对象服务,总有一块Survivor区域是空闲的,因此,新生代实际可用内存空间为9/10(即90%)的新生代空间, Survivor的两个区是对称的,没先后关系,from和to是相对的。

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

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

相关文章

python数据分析——数据可视化(图形绘制基础)

数据可视化(图形绘制基础) 前言一、图形绘制基础Matplotlib简介使用过程sin函数示例 二、常用图形绘制折线图的绘制plot示例 散点图的绘制plot示例 柱状图的绘制bar示例 箱型图绘制plot.box示例 饼状图的绘制pie示例 三、图形绘制的组合情况多个折线图的…

MacOS docker 安装与配置

orbstack 安装 官网: https://orbstack.dev 下载链接:Download OrbStack Fast, light, simple Docker Desktop alternative 选择是Apple M系列处理器, 或 Intel系列处理器 到这里就安装好了Orbstack软件,下面开始配置docker 下…

Python-VBA函数之旅-vars函数

目录 一、vars函数的常见应用场景 二、vars函数使用注意事项 三、如何用好vars函数? 1、vars函数: 1-1、Python: 1-2、VBA: 2、推荐阅读: 个人主页:https://myelsa1024.blog.csdn.net/ 一、vars函数…

MySQL旧表做分区流程

1. 为什么做分区 数据库分区是将数据库中的数据划分成独立的部分,每个部分称为一个分区。分区可以根据特定的标准,如范围、列表或哈希值,将数据分隔到不同的物理存储位置中。数据库表分区可以在多种情况下提供显著的好处。以下是一些应该考虑…

查询中Split函数不管用?试试这个自定义函数!

hi,大家好! 我们在实际的应用中会有这样的一些情况,获取的一些数据是由一些特殊字符连接起来的,比如:XXX汽车\SUV\EV\纯电。类似这样的数据,我们在应用过程中,需要将数据拆开,如果用…

是德keysight N1911A与N1913A单通道功率计

Agilent N1911A和N1912A P系列单通道和双通道功率计以及N192XA传感器可提供宽带宽和高性能测量,这是确保用户的产品符合其功率规范所需要的。 P系列功率计具有30MHz视频带宽和每秒100M/s 的持续采样率,可进行快速、准确、可重复的功率测量。当这些功…

uview-plus在uniapp项目中单选和复选框不显示问题

在我的uniapp小程序项目中,我使用了vue3ts的组合,ui组件库使用了uview-plus这个组件库,但是在使用个别组件的时候,没有显示出效果,就像单选或者复选框,官方效果: 但是当我用到自己项目中的时候&…

【全开源】Java同城信息付费系统家政服务房屋租赁房屋买卖房屋装修信息发布平台小程序APP公众号源码

同城信息付费系统:家政服务的新篇章 在快节奏的现代生活中,家政服务已成为许多家庭不可或缺的一部分。然而,如何快速、准确地找到合适、可靠的家政服务人员,一直是困扰着许多家庭的问题。为了解决这一难题,我们推出了…

一图流解释Java中线程状态的转换

目录 一.Java中的几大线程状态 二.线程之间的相互转换 ▐ NEW --> RUNNABLE ▐ RUNNABLE <--> WAITING ▐ RUNNABLE <--> Timed Waiting ▐ RUNNABLE<--> BLOCKED ▐ RUNNABLE<-->TERMINATED 一.Java中的几大线程状态 简单来说线程可以处于…

PCIE协议-2-事务层规范-Message Request Rules-Vendor_Defined Messages

2.2.8.6 厂商定义消息 厂商定义消息允许扩展PCI Express消息功能&#xff0c;可以作为PCI Express规范的一般扩展&#xff0c;也可以是厂商特定的扩展。本节通用地定义了与这些消息相关的规则。 厂商定义消息&#xff08;见表2-25&#xff09;使用图2-28中显示的头标格式。re…

银行核心背后的落地工程体系丨混沌测试的场景设计与实战演练

本文作者&#xff1a; 张显华、窦智浩、卢进文 与集中式架构相比&#xff0c;分布式架构的系统复杂性呈指数级增长&#xff0c;混沌工程在信创转型、分布式架构转型、小机下移等过程中有效保障了生产的稳定性。本文分享了 TiDB 分布式数据库在银行核心业务系统落地中进行混沌测…

问题—前端调用接口url多加一个/,本地可以调通,测试环境报错302,分开调两个接口

问题背景 接口url前面多加一个/ &#xff0c;npm run serve 起项目&#xff0c;本地调用正常 npm run build 打包到测试环境&#xff0c;接口出现问题&#xff0c;分开调用接口&#xff0c;且报302错误 问题原因&#xff1a; 本地开发环境和测试环境的URL处理方式不同 本地使…

动态规划-两个数组的dp问题3

文章目录 1. 两个字符串的最小ASCII删除和&#xff08;712&#xff09;2. 最长重复子数组&#xff08;718&#xff09; 1. 两个字符串的最小ASCII删除和&#xff08;712&#xff09; 题目描述&#xff1a; 状态表示&#xff1a; 根据经验以及题目要求&#xff0c;建立二维数…

旧手机-基于Termux配置服务器(不用拿去换钢盆了)

Hi&#xff0c;大家好&#xff0c;我是抢老婆酸奶的小肥仔。 大家用手机这么多年了&#xff0c;手上或多或少都有一两个被替换下来的旧手机&#xff0c;也不用拿去换啥钢盆了&#xff0c;使用Termux可以将旧手机改造成一个服务器。 不多说&#xff0c;直接开干。 1、安装app…

别再找了!吐血整理ChatGPT 3.5/4.0新手使用手册

引领科技潮流的ChatGPT早已名声在外&#xff0c;如今获取ChatGPT已变得触手可及&#xff0c;但很多人还多次提问如何使用chatgpt&#xff0c;为了避免陷入误区&#xff0c;本文旨在为广大ChatGPT爱好者提供一份实用的指南。 因此&#xff0c;帮助大家更好地掌握其使用技巧&…

leetcode.环形链表问题

目录 题目1 示例 解题思路 代码实现 补充 题目2 示例 解题思路 代码实现 题目1 该题链接&#xff1a;https://leetcode.cn/problems/linked-list-cycle/description/ 示例 解题思路 要创建两个指针一个是快指针(fast)&#xff0c;另一个慢指针(slow)。快指针走两步慢指…

Linux修改终端命令颜色

1.在家目录中修改.bashrc文件 cd ~ vim .bashrc2.找到PS1相关段落&#xff0c;把其他的注释掉&#xff0c;填上该行代码&#xff0c;修改为自己设置的颜色 (具体颜色查看参考文章) 提供两种颜色&#xff0c;其他的自学调色盘吧(下文有)~ (祝你愉快) ①浅蓝色 深蓝 PS1\[\03…

CSRF 攻击实验:Token 不存在绕过验证

前言 CSRF&#xff08;Cross-Site Request Forgery&#xff09;&#xff0c;也称为XSRF&#xff0c;是一种安全漏洞&#xff0c;攻击者通过欺骗用户在受信任网站上执行非自愿的操作&#xff0c;以实现未经授权的请求。 CSRF攻击利用了网站对用户提交的请求缺乏充分验证和防范…

基于Java+SpringBoot+vue+elementui 实现猜灯谜答题抽奖系统

目录 系统简介效果图1、手机答题端2、后台系统管理 源码结构源码下载地址技术交流 博主介绍&#xff1a; 计算机科班人&#xff0c;全栈工程师&#xff0c;掌握C、C#、Java、Python、Android等主流编程语言&#xff0c;同时也熟练掌握mysql、oracle、sqlserver等主流数据库&…

MES系统在电线电缆行业生产上的应用

MES系统在线缆行业的应用可以带来多重价值&#xff0c;包括提高生产效率、降低生产成本、提高产品质量、优化库存管理、改善生产环境和提高企业竞争力等方面。因此&#xff0c;在电线电缆行业中广泛应用MES系统可以提高企业的经济效益和社会效益&#xff0c;推动企业发展和行业…