别再混淆了!JVM内存模型和Java内存模型的本质区别

JVM内存模型 Java内存模型 Java内存模型是共享内存的并发模型,线程之间主要通过读-写共享变量(堆内存中的实例域,静态域和数组元素)来完成隐式通信。 Java 内存模型(JMM)控制 Java 线程之间的通信,决定一个线程对共享变量的写入何时对另一个线程可见。 计算机高速缓存和缓存一致性 计算机在高速的 CPU 和相对低速的存储设备之间使用高速缓存,作为内存和处理器之间的缓... 阅读详情

JVM 内存模型(JVM Memory Model)和 Java 内存模型(Java Memory Model, JMM)是 Java 开发中两个非常重要的概念,但这两个概念很容易被搞混,所以本文就来通俗易懂的讲讲二者的区别。

首先,我们先来看看各自的概念,以及其解决的问题。

1.JVM内存模型

  • 定位:JVM 在运行 Java 程序时对物理内存的具体划分和管理方式,用来保证 Java 程序正常执行的。

  • 目的:定义 Java 程序在运行时如何分配、使用和回收内存。
  • 核心组成: 堆(Heap):存储对象实例(所有线程共享)。 方法区(Method Area):存储类信息、常量等(JDK8 后由元空间实现)。 虚拟机栈(VM Stack):存储方法的局部变量、操作数栈(每个线程私有)。 本地方法栈(Native Method Stack):服务于 JVM 调用本地方法。 程序计数器(Program Counter Register):记录线程当前执行的指令地址。
  • 关注点:内存的分配、垃圾回收(GC)、内存泄漏等问题。

JVM不划分内存区域行不行?

从理论上来讲可能是可行的,但从程序的运行效率、垃圾回收的效率等方面来讲不划分内存区域,所有的信息放到一起,其效率是非常慢的,是不能被允许的。

并且不划分区域可能会导致关键数据易被污染的问题,例如方法区存储的类元数据(如类结构、静态变量)需要长期存在且全局共享,若与临时变量混存,可能导致类信息被意外覆盖。例如,在热加载类时,新类元数据可能覆盖正在被其他线程使用的旧版本,引发不可预知的错误。

所以综合来看,JVM 必须按存储的数据类型划分为不同的数据区域,以提升程序的执行和垃圾回收的效率,并且可以减少程序在运行时的一些不必要的问题,这就是 JVM 内存模型所解决的问题。

2.Java内存模型

  • 定位:Java 语言规范(JLS)定义的多线程环境下内存访问的规则和约束的一种规范。

  • 目的:解决多线程并发时的内存可见性、原子性、有序性问题,确保线程间正确通信。
  • 核心概念: 主内存(Main Memory):所有线程共享的内存区域。 工作内存(Working Memory):每个线程私有的内存副本(可能对应 CPU 寄存器或缓存)。 happens-before原则:定义操作之间的偏序关系,确保可见性。 内存屏障(Memory Barriers):禁止指令重排序的机制。
  • 关注点:如何通过 synchronized、volatile 等关键字或并发工具类保证线程安全。
  • 示例场景:解决多线程下共享变量的不可见性(如使用 volatile 禁止指令重排序)。

PS:也就是说“Java 内存模型”主要是保证 Java 在多线程下正常运行的一种机制(或规定)。

小结

JVM内存模型

Java内存模型(JMM)

范畴

JVM 实现层面的内存区域划分

多线程并发编程的内存访问规则

主要目标

内存分配、回收和管理

解决线程间的可见性、有序性和原子性问题

具体实现

堆、栈、方法区等物理内存划分

volatile、synchronized 等语义

内存模型(Memory Model)是什么? 内存模型是定义多线程程序中内存访问行为的核心规则,主要解决两个问题:1)线程写操作对其他线程的可见性;2)内存操作的重排序限制。现代计算机因缓存一致性和指令重排序(编译器/CPU优化)导致并发访问复杂化,内存模型通过硬件层(如x86/ARM差异)和语言层(如Java/C++抽象)建立统一契约。关键概念包括内存序(顺序一致/获取-释放/松散),通过内存屏障和原子操作平衡性能与正确性,使多线程程序行为可预测。 阅读详情

相关推荐

一文读懂Memory consistency model (内存模型)

本文介绍了计算机系统中各种常见的memory model(内存模型)以及优缺点。

W1Z1Q的专栏 4647

JMM(Java内存模型)详解

1.什么是JMM? ​ JMM 是Java内存模型( Java Memory Model),简称JMM。它本身只是一个抽象的概念,并不真实存在,它描述的是一种规则或规范。通过这组规范,定义了程序中对各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式。 ​ 计算机在执行程序时,每条指令都是在CPU中执行的。而执行指令的过程中,势必涉及到数据的读取和写入。由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这时就存在一个问题,由于CPU执行速度很快,而从内存读取数据和向内存写入数据的过

LYQ20010417的博客 3万+

JDK、JRE、JVM本质区别与工程实践指南

JDK、JRE、JVM是Java运行体系的三层核心抽象:JVM作为字节码执行引擎,是跨平台能力的技术根基;JRE为其提供标准类库与运行时支持,构成最小可执行环境;JDK则在JRE基础上集成编译器(javac)、调试器(jdb)、性能分析工具(jstat/jmap)等开发必需组件。这种分层设计源于责任分离——JVM专注指令执行,JRE保障程序运行,JDK支撑全生命周期开发。在云原生与容器化场景下,轻量级JRE(如openjdk:17-jre-headless)成为生产部署首选,而JDK仍是构建、调试与问题诊断

411

JMM概述

简介什么是JMM内存模型可以理解为在特定的操作协议下,对特定的内存或者高速缓存进行读写访问的过程抽象描述,不同架构下的物理机拥有不一样的内存模型,Java虚拟机是一个实现了跨平台的虚拟系统,因此它也有自己的内存模型,即Java内存模型(Java Memory Model, JMM)。因此它不是对物理内存的规范,而是在虚拟机基础上进行的规范从而实现平台一致性,以达到Java程序能够“一次编写,到处运行

牧竹子 6万+

别再搞混了!深入浅出理解Java线程中start()和run()的本质区别

run()它只是一个普通的方法。它定义了线程要执行的任务内容,就像一份“菜谱”。当你直接调用时,就相当于你(当前线程)亲自按照这份菜谱去做菜。这不会产生任何新的线程。start()它是一个神奇的启动命令。它的作用是为run()方法里的“菜谱”聘请一位专门的厨师(新线程)。JVM在收到start()指令后,会创建一个新的执行线程,并由这个新线程在后台自动去调用和执行run()方法。start()和run()的区别,是Java多线程编程的基石概念。run():是任务本身。它定义了“做什么”。start():是。

zhaostars的博客 607

Java核心技术解析:从JVM到开发实践

Java作为企业级开发的主流语言,其核心技术体系包含JVM、JDK工具链和丰富的类库框架。理解Java虚拟机(JVM)的内存模型和垃圾回收机制是性能优化的基础,而掌握泛型、枚举等语法特性则能提升代码质量。在实际开发中,Lombok等工具可以显著提高效率,但需要注意版本兼容性问题。Java集合框架的设计思想和高并发解决方案是面试常见考点,合理使用HashMap、ConcurrentHashMap等容器对系统性能至关重要。随着模块化系统和现代语法特性的引入,Java持续保持技术竞争力,适用于微服务、大数据等热门

weixin_28455801的博客 241

JVM 内存模型详解

JVM 运行时数据区分为线程私有(程序计数器、虚拟机栈、本地方法栈)和线程共享(堆、方法区),其中堆是 GC 核心区域;虚拟机栈易出(栈深度超限),堆易出(堆内存不足),元空间(JDK8+)也可能因类元数据过多溢出;理解内存模型的核心价值:能定位内存溢出 / 泄漏问题,优化 JVM 参数,提升程序稳定性。

2502_92141759的博客 977

Java面试核心:JVM内存管理与HashMap原理详解

JVM内存管理是Java性能优化的核心领域,涉及堆内存、方法区、虚拟机栈等关键区域的精细划分。通过分代收集算法和GC机制,JVM实现了高效的内存回收,而内存泄漏和OOM异常等问题则需要借助jmap、jstat等工具进行排查。HashMap作为Java集合框架的重要组成,采用数组+链表+红黑树的结构解决哈希冲突,其扩容机制和线程安全特性是面试高频考点。理解这些底层原理不仅能帮助开发者编写高性能代码,也是通过大厂Java技术面试的关键。本文结合JVM内存模型和HashMap实现细节,为读者揭示Java核心技术背

weixin_30565199的博客 408

第1篇:一段旅程的开始——JVM内存模型简介

本文介绍了Java虚拟机(JVM)的内存模型(运行时数据区),分为线程私有和共享区域。私有区域包括程序计数器、Java虚拟机栈和本地方法栈,随线程生灭;共享区域包含堆和方法区,是GC主战场。堆存储对象实例,方法区保存类信息、常量等。JDK8后方法区改用元空间,避免OOM。理解这些区域对性能调优和问题排查至关重要。文章还概述了执行引擎的作用,并总结了各区域特性及常见异常。

2503_90542405的博客 827

Java数组声明:从基础语法到内存模型与性能优化的深度解析

数组作为计算机科学中最基础的数据结构之一,本质上是连续内存空间的抽象,用于存储相同类型的数据集合。其核心原理在于通过索引实现O(1)时间复杂度的随机访问,这种特性使其在性能敏感场景中具有不可替代的价值。在Java语言中,数组不仅是基本数据类型和对象的容器,更是理解JVM内存模型和引用机制的绝佳切入点。从技术价值看,掌握数组的声明、创建与初始化三阶段,能有效避免NullPointerException和ArrayIndexOutOfBoundsException等常见运行时异常,这是构建健壮Java应用的基石

weixin_30444111的博客 262

告别Windows!Oculus Quest 2在Mac M1上的串流实战(scrcpy+SideQuest避坑指南)

本文为Mac M1用户提供了Oculus Quest 2在macOS上实现高清低延迟串流的实战指南。通过使用开源工具scrcpy和SideQuest,绕开官方限制,详细讲解了从环境准备、无线调试到画质与延迟优化的完整步骤,重点解决了Apple Silicon芯片Mac的连接与性能问题,助你告别Windows依赖。

weixin_29224309的博客 311

【杂项知识点】一文搞懂 JVM、JRE 与 JDK:从概念混淆到生产部署

JVM、JRE、JDK 是每个 Java 开发者绕不开的三个核心术语,但很多人在配置环境时仍然分不清"装哪个才对"。 本文从核心定义出发,用俄罗斯套娃式的层级关系图理清三者的嵌套逻辑(JDK ⊃ JRE ⊃ JVM),配合对比表格、代码示例和三种真实场景(终端用户/开发者/运维诊断),讲透"谁在何时用什么"。 同时纠正三个高频误区——为什么服务器不该装 JDK、为什么 JVM 不只跑 Java、为什么 JRE 不等于类库合集,帮你从"背概念"升级到"理解架构"。

超级苦力怕的博客 2547

IS-IS协议深度解析(二):LSDB同步机制与骨干网实战部署

本文深度解析IS-IS协议的LSDB同步机制与骨干网实战部署。详细阐述了DIS角色如何通过CSNP/PSNP报文高效管理链路状态数据库同步,并与OSPF DR机制进行对比。重点介绍了Level-2骨干网作为逻辑高速公路系统的工作原理,以及通过ATT比特位实现跨区域路由的自动化。最后提供了高可靠性骨干网的实战配置要点与验证方法。

kite3的博客 644

别再混淆了!JavaScript与Java的10个本质区别(附常见面试题解析)

本文详细解析了JavaScript与Java的10个本质区别,包括基因差异、执行环境、类型系统、面向对象、并发模型等核心方面,并附有常见面试题解析。帮助开发者深入理解这两种语言的技术特点,提升面试表现和技术选型能力。

weixin_29011239的博客 341

关于图像傅里叶变换得到的频谱图的通俗理解

傅里叶变换过程: 经过傅里叶变化且频谱居中化处理的频谱图: 1.如果将图像某一行上的灰度变化看作是一个离散信号,那么整张图像可以看作是一个分布在二维平面上的信号,因此图像可看作是空间域信号。傅里叶变换则是将图像灰度分布(空间域信号)变换到了频域上,给我们提供了观察图像的另一个视角。 2.图像的频谱图(频谱居中后)的中心点是频率最低点,以该点为圆心,不同半径的上的点表示不同的频率。这里的图像频率是指对应原图像中的某灰度曲线变化的快慢(这么说不严谨,但是按照上面第1点的角度,似乎也可以这么理解

daimashiren的博客 2万+

【小白教程】本地部署VLM-R1模型(使用Docker)

通过Docker本地部署VLM-R1大模型,详细教程。

m0_69855053的博客 2944

别再混淆了!JavaScript与Java的10个本质区别(前端开发者必备知识)

本文详细解析了JavaScript与Java的10个本质区别,特别针对前端开发者。从语言基因、类型系统、面向对象到并发模型,全面对比两种语言的核心差异,帮助开发者避免混淆并提升开发效率。重点探讨了JavaScript的动态类型、原型链和事件循环等特性,为Java背景的开发者提供实用转换指南。

weixin_42558257的博客 264

基于OSPF技术的某企业网络设计(完整文档+ENSP拓扑图)

主要对网络规划与设计,以企业网络为背景,对某个中型企业网络进行规划设计,该企业总部在南京,在常州有一个分公司,需要实现总部和分公司能够访问外网,能够让分公司内的用户或主机访问总部服务器的资源,并且保证数据的安全性。在这次总部企业网络设计中,考虑到资金的问题,核心层部署2台核心三层交换机,负责转发总部内部用户的流量,并充当内部用户网关,能够实现内部不同网段的用户之间的连通性。对于一些对网络比较敏感的企业或用户,对网络的要求较高,对于网络的稳定性和安全性也有较高的要求。

qq1325513482的博客 2万+

谈谈JVM内存泄漏与内存溢出的区别

本文深入剖析了Java中的内存泄漏(Memory Leak)与内存溢出(Out Of Memory)的核心区别。内存泄漏指无用对象因被意外引用而无法被回收,导致内存逐渐耗尽;内存溢出则是内存不足无法分配新对象导致的程序崩溃。文章通过JVM内存模型图示、典型代码示例和对比表格,清晰展示了两者在定义、成因、表现和诊断方法上的差异。内存泄漏可能引发内存溢出,但溢出也可能是由其他原因导致。诊断内存泄漏需借助专业工具分析对象引用链,而内存溢出则可通过错误日志快速定位。

m0_66884848的博客 841

教程:使用树莓派连接Pixhawk飞控

教程:使用树莓派连接Pixhawk飞控树莓派可以与Pixhawk飞控相连,读取飞控中的状态信息,同时对飞控发送指令。树莓派作为一个更高性能的计算平台,可以运行图像识别、机器学习、实时路径规划等程序,为开源无人机带来了无限可能。本文将介绍如何在树莓派上使用APSync。不需要了解Linux,即可将树莓派连接到Pixhawk飞控。使用的器材为: Pixhawk飞控 树莓派3B(Raspberry Pi

Roger今天好好搬砖了吗 5万+

OpenVins解析:基于滤波框架的SLAM

这一方式存在的关键问题是匹配耗时很长,对性能影响显著。可以参考ORBSLAM3中的匹配方式来对其优化,比如左右目匹配可以在极线上搜索,前后帧可以利用运动先验投影匹配。理论上加入路标点会提升精度,代价是增加了计算量。着重说下基于描述子的匹配:OpenVins中匹配的方式是robust_match(),里面是调用的opencv的。openvins中不仅仅进行了传统的MSCKF更新(状态向量中不包含路标点),还在。中进行了包含路标点的估计更新。图像帧到来时,利用IMU递推得到的位姿给该图像帧赋初值。

qq_18076309的博客 4081

Java学习—— static 关键字的全场景用法、类变量与实例变量的本质区别

static是 Java 的静态修饰符将成员归属于类本身,而非某个实例对象,被 static 修饰的成员会在类加载时初始化,不依赖任何对象调用。static 可修饰4 种语法元素成员变量 →类变量(静态变量)成员方法 →静态方法(类方法)代码块 →静态代码块内部类 →静态内部类类变量(static 变量):被 static 修饰的成员变量,属于类,全类所有对象共享一份;实例变量(非 static 变量):无 static 修饰的成员变量,属于单个对象,每个对象独有一份。核心:static 修饰的成员。

2402_83462390的博客 508

【图像超分】论文复现:Pytorch实现SRCNN!保姆级复现教程!提供完整代码和最优权重模型(x2、x3、x4)!科研级论文曲线图!计算平均PSNR和SSIM!代码Windows和Linux都可用!

由于很多同学反应没用过jupyter notebook,更习惯用pycharm项目的形式跑代码。于是,本文将用pycharm项目的形式,重新复现SRCNN!【图像超分】论文复现:新手入门!Pytorch实现SRCNN,数据预处理、模型训练、测试、评估全流程详解,注释详细,简单修改就可以训练你自己的图像数据,有训练好的模型下载地址,随取随用。

主要更新底层视觉(去噪、超分等)相关的科研内容,形式为【论文精读】+【论文复现】 4705
上一篇: 面试官:谈谈你对线程池拒绝策略的理解?
下一篇: 数据分析实战项目——电商用户行为分析及可视化(基于SQL/Tableau 含代码)
程序员职业指南
博客等级 码龄4年 2139粉丝 960原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值