网站开发和室内制作深圳建设工程交易信息网
- 作者: 五速梦信息网
- 时间: 2026年03月21日 07:37
当前位置: 首页 > news >正文
网站开发和室内制作,深圳建设工程交易信息网,兰州网站建设 冰雨,搜索seo引擎目录 1、JVM 内存 1.1、分配机制 1.2、jvm模型位置 1.3、字节码内存块 2、JMM内存 2.1、JMM模型 2.2、工作流程图 1、工作内存与主内存的交互
- 多线程下的主内存与堆内存交互 2.3、 主内存与工作内存的同步方案 1、volatile 2、synchronized 3、final 3、内存使…目录 1、JVM 内存 1.1、分配机制 1.2、jvm模型位置 1.3、字节码内存块 2、JMM内存 2.1、JMM模型 2.2、工作流程图 1、工作内存与主内存的交互
- 多线程下的主内存与堆内存交互
2.3、 主内存与工作内存的同步方案
1、volatile
2、synchronized
3、final
3、内存使用
3.1、集群环境
3.2、容器化环境
3.3、示例场景
4、常见问题与解决方案 前言 在日常开发过程中不知道你是否考虑JVM内存模型、JMM模型、计算机内存模型它们是通过何种机制来进行联系的。
问题 比如当选择一台物理机器节点部署应用的时候如何选择规模适度的内存大小选择了计算机内存后如何为程序应用选择JVM内存大小。 在jvm内存大小设定好JMM模型是如何用jvm交互的呢本篇将介绍下它们的联系及内存分配。 1、JVM 内存
1.1、分配机制 JVM运行内存分配时其最终由 操作系统 管理。 JVM 的内存参数如 -Xms、-Xmx只是告诉 JVM 它期望使用的内存范围但实际使用的内存是 运行 JVM 的物理机器或虚拟机节点的内存。
如下图所示 根据上面可以看出 JVM内存模型是模仿操作系统内存模型构建的JVM内存模型和操作系统内存模型是可以一一对应起来的。 1.2、jvm模型位置
关于jvm内存模型可参考关于对JVM的知识整理_jvm知识-CSDN博客 JVM就类似于一个操作系统整个JVM内存模型存储在操作系统的堆中。 如下图所示 1、方法区 而JVM的方法区也就相当于操作系统/主机的硬盘区也叫永久区而操作系统栈(本地方法栈)和JVM的栈也是一致的
2、堆 JVM堆和操作系统堆在概念上和目标上是一致的分配内存的方式也是一致的但JVM堆管理垃圾的方式是GC回收而操作系统堆则是需要程序员手动释放
3、PC寄存器 计算机上的PC寄存器是计算机上的硬件(是CPU内部用来存放“伪指令”或地址数据的一些小型存储区域)。 而对于虚拟机PC寄存器它表现为一块内存(一个字长虚拟机要求字长最小为32位)存放的是将要执行指令的地址。 1.3、字节码内存块
关于更多方法区的介绍可参考关于对JVM的知识整理_jvm知识-CSDN博客 ClassLoader这个类加载器存放在堆内存当一个classLoder启动的时候它会去主机硬盘上将A.class加载到jvm的方法区。 如下所示 方法区里面的字节文件会被虚拟机读取并执行new A字节码()然后在堆内存生成了一个A字节码的对象。
此时方法区里面A字节码内存文件有两个引用 一个指向A的class对象一个指向加载自己的classLoader引用。 如下图。 ⚠️注意图里面的字段信息应该是字段的结构信息方法区而不是字段的值堆内存。 对比字节码内存块和类的信息。
代码示例
public final class ClassStruct extends Object implements Serializable {// 实例变量的值存储在堆内存// 实例变量的结构信息存放在方法区private String name;private int id;// 静态常量存储在方法区public final int CONST_INT 0;public final String CONST_STR CONST_STR;// 静态变量存储在方法区public static String static_str static_str;// 静态方法字节码存储在方法区public static final String getStatic_str() throws Exception {return ClassStruct.static_str;}
}结论jvm方法区里面的字节码内存就是将完整的类信息加载到了内存。 参考类的信息
ClassStruct
├── 类名: ClassStruct
├── 父类: java.lang.Object
├── 接口: java.io.Serializable
├── 字段:
│ ├── name: private java.lang.String
│ ├── id: private int
│ ├── static_str: public static java.lang.String
│ ├── CONST_INT: public final int
│ └── CONST_STR: public final java.lang.String
├── 方法:
│ └── getStatic_str(): public static final
└── 常量池:├── static_str├── CONST_STR└── 01.类信息修饰符(public final) 是类还是接口(class,interface) 类的全限定名(Test/ClassStruct.class) 直接父类的全限定名(java/lang/Object.class) 直接父接口的权限定名数组(java/io/Serializable) public final class ClassStruct extends Object implements Serializable这段描述的信息提取 2.字段结构信息修饰符(pirvate) 字段类型(java/lang/String.class) 字段名(name) private String name;这段描述信息的提取。实例变量的值存放在堆内存里面 3.方法信息:修饰符(public static final) 方法返回值(java/lang/String.class) 方法名(getStatic_str) 参数需要用到的局部变量的大小还有操作数栈大小(操作数栈) 方法体的字节码(就是花括号里的内容) 异常表(throws Exception) public static final String getStatic_str ()throws Exception的字节码的提取 4.常量池: 整型直接常量池public final int CONST_INT0; 字符串直接常量池 public final String CONST_STRCONST_STR; 浮点型直接常量池 方法名、方法描述符、类名、字段名字段描述符的符号引用 5.类变量 就是静态字段( public static String static_strstatic_str;) 虚拟机在使用某个类之前必须在方法区为这些类变量分配空间。 6.一个到堆内存classLoader的引用 通过this.getClass().getClassLoader()。 7.一个到堆内存class A对象的引用 这个对象存储了所有这个字节码内存块的相关信息。 可使用反射java的反射详解_java中的反射-CSDN博客
1、类信息你可以通过this.getClass().getName()取得
2、所有的方法信息可以通过this.getClass().getDeclaredMethods()。
3、字段信息可以通过this.getClass().getDeclaredFields()。 2、JMM内存 2.1、JMM模型 Java 内存模型Java Memory Model, JMM定义了多线程环境下变量的可见性、原子性和有序性规则。 如下图所示
Java 内存模型JMM
├── 主内存所有线程共享
│ ├── 堆内存对象实例、数组
│ ├── 方法区类元数据信息、常量池、静态变量、字节码文件
│ └── 静态变量
└── 工作内存每个线程私有├── 虚拟机栈局部变量└── 本地方法栈Native 方法使用1、堆内存与JMM 主内存的联系 JVM 堆内存是 Java 内存模型JMM中主内存的一部分。 堆内存中的对象属于主内存 所有在堆中创建的对象如 new object()存储在 JMM 的主内存中。多线程共享这些对象线程通过工作内存如 CPU 缓存读写堆内存中的对象。 JMM 的主内存范围更广
主内存 不仅包含堆内存还包括 方法区存储类信息、静态方法和字段、常量池、字节码文件等JDK 8 后移至元空间 Metaspace。 静态变量存储在方法区。 局部变量存储在虚拟机栈中但变量引用的对象存储在堆中。 主内存 vs 工作内存 主内存所有线程共享的物理内存包括堆、方法区等。 工作内存每个线程私有的本地内存如 CPU 寄存器、高速缓存用于临时存储变量副本。 注意堆内存 是主内存中用于存储对象实例的核心部分。 总结 2.2、工作流程图
1、工作内存与主内存的交互 2. 多线程下的主内存与堆内存交互
1、变量读写流程
线程访问变量 如果变量在主内存如堆中的对象字段线程会将变量复制到工作内存。修改后线程将更新后的值写回主内存通过 happens-before规则保证可见性。 2、内存可见性问题
默认情况下线程对变量的修改对其他线程不可见因为工作内存和主内存的同步延迟。解决方案 使用 volatile 关键字强制每次读写都直接访问主内存。使用 synchronized 或 Lock通过锁机制确保内存同步。
代码示例 public class JMMExample {private int sharedVariable 0; // 存储在堆内存主内存public void increment() {int localVariable this.sharedVariable; // 从主内存读取到工作内存localVariable;this.sharedVariable localVariable; // 将修改后的值写回主内存} }线程 A 执行 increment() 从主内存堆读取 sharedVariable 到工作内存。修改后写回主内存。 线程 B 读取 sharedVariable 如果未使用 volatile 或 synchronized可能读取到旧值工作内存未同步。 2.3、 主内存与工作内存的同步方案 1、volatile 关于volatile的实现详细可参考对于Synchronized和Volatile的深入理解_java sychronized和volatile以及同步代码块-CSDN博客 private volatile int sharedVariable 0;作用禁止线程缓存变量副本每次读写直接操作主内存。 2、synchronized 关于synchronized的实现可参考对于Synchronized和Volatile的深入理解_java sychronized和volatile以及同步代码块-CSDN博客 public synchronized void increment() {sharedVariable; }作用通过锁确保变量的修改对其他线程可见。 3、final 关于final的具体应用可参考对于final、finally和finalize不一样的理解-CSDN博客 private final int sharedVariable 0;作用final 变量在构造函数结束后对其他线程可见。 3、内存使用 3.1、集群环境 在 集群部署如 Kubernetes、Docker Swarm、物理服务器集群中每个 JVM 实例运行在某个 节点Node 上。 JVM 的内存分配规则如下 1、节点物理内存 vs JVM 堆内存 1.JVM 堆内存Heap Memory 通过 -Xms初始堆大小和-Xmx最大堆大小参数配置。这些参数控制的是 JVM 堆内存但它会占用 所在节点的物理内存。 例如-Xmx4g 表示 JVM 最多可以使用 4GB 节点内存用于堆。 2.非堆内存Metaspace、Direct Memory 等 Metaspace类元数据默认无上限需通过 -XX:MaxMetaspaceSize 限制。 直接内存Direct Memory通过 -XX:MaxDirectMemorySize 配置同样占用节点物理内存。 如下图所示 3.2、容器化环境 如Docker/Kubernetes。 1、容器内存限制 如果 JVM 运行在容器中如 Docker 容器容器的内存限制如 –memory4g 或 Kubernetes 的 resources.limits.memory会 限制 JVM 可使用的总内存。 JVM 无法突破容器内存限制否则会被操作系统强制终止OOMKilled。 2、JVM 参数与容器限制的关系 -Xmx 应小于容器内存限制的 70%-80%为其他组件如非堆内存、OS 缓存预留空间。例如容器内存限制为 4GB则 -Xmx 建议设为 3g。 3.3、示例场景 1物理服务器集群 节点配置8GB 内存。JVM 配置-Xmx4g。实际内存使用JVM 最多占用 4GB 节点内存堆内存其余内存可用于其他服务如数据库、中间件。 2Kubernetes 集群 Pod 配置resources.limits.memory4Gi。JVM 配置-Xmx3g。实际内存使用JVM 最多占用 3GB 容器内存剩余 1GB 用于非堆内存和容器内其他进程。 4、常见问题与解决方案 1、JVM 报 OOM 但节点内存充足 原因 JVM 堆内存未配置导致堆内存无限制。非堆内存如 Metaspace未限制导致内存泄漏。 解决方案 显式设置 -Xmx 和 -XX:MaxMetaspaceSize。监控 JVM 内存使用如通过 Prometheus Grafana。
2、容器被 OOMKilled 原因 JVM 堆内存 非堆内存 容器其他进程内存总和超过容器限制。 解决方案 降低 -Xmx为非堆内存和系统开销预留空间。使用容器内存配额如 Kubernetes 的 resources.limits.memory。 参考文章 1、JVM内存是对应到操作系统内存_jvm内存和电脑内存的关系-CSDN博客 2、关于对JVM的知识整理_jvm知识-CSDN博客
相关文章
-
网站开发和前端和数据媒体建设网站业务竞争大
网站开发和前端和数据媒体建设网站业务竞争大
- 技术栈
- 2026年03月21日
-
网站开发和平台开发新闻门户网站制作
网站开发和平台开发新闻门户网站制作
- 技术栈
- 2026年03月21日
-
网站开发和安卓开发怎么做韩剧网站的翻译
网站开发和安卓开发怎么做韩剧网站的翻译
- 技术栈
- 2026年03月21日
-
网站开发和网络工程哪个好wordpress阿里云插件
网站开发和网络工程哪个好wordpress阿里云插件
- 技术栈
- 2026年03月21日
-
网站开发和网络工程师织梦 音乐网站
网站开发和网络工程师织梦 音乐网站
- 技术栈
- 2026年03月21日
-
网站开发和游戏开发深圳市宝安区龙华公司是干什么的
网站开发和游戏开发深圳市宝安区龙华公司是干什么的
- 技术栈
- 2026年03月21日
