JVM简介

article/2025/6/7 13:17:22
  1. JAVA内存模型

以下是关于 Java内存模型(JMM) 的核心要点总结:

一、JMM的核心作用

Java内存模型是 **多线程环境下内存访问的规范**,主要解决以下问题:

  1. 可见性:线程对共享变量的修改对其他线程立即可见(避免CPU缓存不一致)。

  2. 原子性:确保指令执行不受线程切换影响(如volatilesynchronized或原子类)。

  3. 有序性:防止CPU指令重排序(通过内存屏障实现)。

二、JMM的内存结构

组件

作用

主内存

存储所有共享变量(线程间可见)。

工作内存

线程私有,存储主内存变量的副本(操作完成后同步回主内存)。

三、关键实现机制

  1. 内存屏障分为LoadLoadStoreStoreLoadStoreStoreLoad四类,用于禁止特定类型的指令重排序。

  2. happens-before规则保证操作的顺序性,例如:

    1. 程序顺序规则

    2. volatile变量的写操作优先于读操作

    3. 锁的释放优先于获取

  3. volatile关键字

    1. 强制从主内存读写变量,禁用缓存优化。

    2. 禁止指令重排序(类似内存屏障)。

四、并发编程实践

场景

解决方案

线程安全计数器

使用AtomicIntegerLongAdder(原子性+可见性)。

单例模式

双重检查锁中需用volatile修饰实例(防止指令重排序)。

状态标志控制

volatile boolean替代锁(轻量级可见性保障)。

五、JMM与JVM内存模型的区别

对比维度

JMM

JVM内存模型

定位

多线程内存访问规范

物理内存区域划分(堆、栈等)

核心问题

可见性、原子性、有序性

内存分配与垃圾回收

典型工具

volatilesynchronized、原子类

JVM参数调优(-Xmx-Xss等)

六、调优工具推荐

  1. MAT(Memory Analyzer Tool):分析堆转储,定位内存泄漏。

  2. JFR(Java Flight Recorder):实时监控内存分配与GC事件。

  3. Arthas:在线诊断线程状态(如thread -n 3查CPU占用、方法执行耗时)。

七、线程上下文切换

Java内存模型(Java Memory Model, JMM)和线程上下文切换之间有着密切的关系。理解这两者的关系有助于编写高效且线程安全的并发程序。

Java内存模型(JMM)

Java内存模型定义了Java程序中变量(包括实例字段、静态字段和构成数组对象的元素)的访问规则。它描述了在多线程环境下,变量的值如何在不同线程之间传递。JMM的主要目标是提供一种机制,使得程序员可以在多线程环境下编写正确的并发程序。

JMM的核心概念包括:

  • 主内存和工作内存:每个线程都有自己的工作内存,工作内存保存了该线程使用到的变量的副本。主内存是所有线程共享的内存区域。

  • 内存可见性:JMM规定了一个线程对变量的写入何时对另一个线程可见。

  • volatile关键字:保证变量的可见性和有序性。

  • synchronized关键字:保证代码块的原子性和可见性。

线程上下文切换

线程上下文切换是指CPU从一个线程切换到另一个线程的过程。上下文切换涉及保存和恢复线程的状态,包括程序计数器、寄存器和变量等。上下文切换是多线程环境下实现并发的基础,但频繁的上下文切换会带来性能开销。

JMM与线程上下文切换的关系

  1. 内存可见性:在多线程环境下,线程上下文切换可能导致内存可见性问题。一个线程对变量的修改在另一个线程中可能不可见。JMM通过定义内存屏障和happens-before关系来解决这个问题,确保线程之间的内存可见性。

  1. 缓存一致性:线程上下文切换时,线程的工作内存(缓存)需要与主内存保持一致。JMM通过规定变量的读取和写入规则,确保线程切换后,变量的一致性。

  1. 指令重排序:为了提高性能,编译器和处理器可能会对指令进行重排序。JMM通过内存屏障和happens-before关系,限制了重排序的范围,确保多线程程序的正确性。

  1. 同步机制:JMM提供的同步机制(如volatile和synchronized)在线程上下文切换时起到了关键作用。它们确保了线程切换时的内存可见性和操作的原子性。

总结

Java内存模型和线程上下文切换共同作用,确保了多线程环境下程序的正确性和性能。理解JMM的工作原理和线程上下文切换的机制,有助于编写高效且线程安全的并发程序。

总结

掌握JMM是编写 高效且线程安全 的Java程序的关键。理解其底层原理(如内存屏障、happens-before规则)能有效避免并发陷阱(如死锁、数据竞争),结合工具可快速定位性能瓶颈。

  1. JVM内存模型

一、JVM内存区域划分

JVM内存模型主要分为线程共享区域线程私有区域

  1. 线程共享区域

    1. 堆(Heap)

      • 存储所有对象实例和数组(约80%对象在此分配)。

      • 细分结构:

        • 新生代(Young Generation)

          • Eden区:新对象首次分配区域。

          • Survivor区(From/To):存放经过Minor GC存活的对象。

        • 老年代(Old Generation):存放长期存活对象(如多次GC未被回收的对象)。

      • 参数调优

        • -Xms(初始堆大小)、-Xmx(最大堆大小)。

        • 建议:两者设置为相同值以避免动态扩容的性能损耗。

    2. 元空间(Metaspace)(JDK 8+)

      • 取代永久代(PermGen),存储类元数据(类结构、方法、常量池等)。

      • 直接使用本地内存(非堆内存),避免PermGen的OOM问题。

      • 参数调优

        • -XX:MetaspaceSize(初始阈值)、-XX:MaxMetaspaceSize(最大上限)。

  2. 线程私有区域

    1. 虚拟机栈(Java Stack)

      • 每个线程对应一个栈,存储方法调用的栈帧(局部变量、操作数栈等)。

      • 栈深度溢出会抛出StackOverflowError

    2. 本地方法栈(Native Method Stack)

      • 为JVM调用本地方法(Native)服务。

    3. 程序计数器(Program Counter Register)

      • 记录当前线程执行指令的位置(线程切换时恢复执行点)。

二、垃圾回收(GC)机制

  1. 分代回收策略

区域GC频率主要算法典型问题
新生代复制算法Eden区快速填满
老年代标记-清除/整理Full GC导致应用停顿
元空间极低无(直接分配)类元数据溢出(OOM)
  1. 优化策略

    1. 避免过早晋升:通过-XX:MaxTenuringThreshold控制对象晋升老年代的阈值。

    2. 大对象直接进老年代:通过-XX:PretenureSizeThreshold设置。

三、常见问题与调优实践

  1. OOM(内存溢出)场景

    1. 堆溢出对象过多或内存泄漏(如未释放集合引用)

    2. 元空间溢出:动态生成大量类(如反射、CGLib)。

    3. 栈溢出深度递归或循环调用

  2. 调优工具

    1. jstat:监控堆内存和GC状态。

    2. jmap:生成堆转储快照(分析内存泄漏)。

    3. VisualVM:图形化监控内存、线程、类加载情况。

四、总结

JVM内存模型的核心在于分代设计垃圾回收策略。通过合理设置堆大小、选择GC算法(如G1/ZGC优化低延迟场景)、监控元空间使用,可显著提升应用性能。关键原则是平衡内存分配与回收效率,减少Full GC频率。

  1. JVM参数

-Xss256k -XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:+UseContainerSupport -XX:MaxRAMPercentage=70.0 -XX:MetaspaceSize=600m -XX:MaxMetaspaceSize=600m -XX:MaxDirectMemorySize=200m -XX:CompressedClassSpaceSize=200m -XX:InitialCodeCacheSize=200m -XX:ReservedCodeCacheSize=200m

这些JVM参数用于配置Java虚拟机的运行时行为和内存管理。以下是每个参数的详细解释:

  1. -Xss256k:设置每个线程的堆栈大小为256KB。默认值通常是1MB或更大,较小的堆栈大小可以减少内存使用,但可能会导致栈溢出错误。

  1. -XX:+UseG1GC:启用G1垃圾收集器(Garbage-First Garbage Collector)。G1GC是一个低暂停时间的垃圾收集器,适用于大多数应用程序。

  1. -XX:MaxGCPauseMillis=100:设置G1垃圾收集器的最大暂停时间目标为100毫秒。G1GC会尝试在这个时间内完成垃圾收集。

  1. -XX:+UseContainerSupport:启用对容器环境的支持,使JVM能够识别和适应容器的资源限制(如CPU和内存)。

  1. -XX:MaxRAMPercentage=70.0:设置JVM可以使用的最大内存为容器或主机可用内存的70%。

  1. -XX:MetaspaceSize=600m:设置元空间(Metaspace)的初始大小为600MB。元空间用于存储类的元数据。

  1. -XX:MaxMetaspaceSize=600m:设置元空间的最大大小为600MB。

  1. -XX:MaxDirectMemorySize=200m:设置直接内存的最大大小为200MB。直接内存用于NIO(非阻塞I/O)操作。

  1. -XX:CompressedClassSpaceSize=200m:设置压缩类空间的大小为200MB。压缩类空间用于存储类指针,以减少内存占用。

  1. -XX:InitialCodeCacheSize=200m:设置代码缓存的初始大小为200MB。代码缓存用于存储JIT(即时编译器)编译的本地代码。

  1. -XX:ReservedCodeCacheSize=200m:设置代码缓存的最大大小为200MB。

这些参数可以根据应用程序的需求进行调整,以优化性能和内存使用。

  1. 垃圾回收


http://www.hkcw.cn/article/WxidrHAvAy.shtml

相关文章

蓝桥杯 k倍区间

题目描述 给定一个长度为 N 的数列,A1,A2,⋯AN,如果其中一段连续的子序列 Ai,Ai1,⋯Aj ( i≤j ) 之和是 K 的倍数,我们就称这个区间 [i,j] 是 K 倍区间。 你能求出数列中总共有多少个 K 倍区间吗? 输入描述 第一行包含两个整数…

linux批量创建文件

文章目录 批量创建空文件touch命令批量创建空文件循环结构创建 创建含内容文件echo重定向多行内容写入 按日期创建日志文件根据文件中的列内容,创建文件一行只有一列内容一行有多列内容 批量创建空文件 touch命令批量创建空文件 # 创建文件file1.txt到file10.txt …

[蓝桥杯]高僧斗法

高僧斗法 题目描述 古时丧葬活动中经常请高僧做法事。仪式结束后,有时会有"高僧斗法"的趣味节目,以舒缓压抑的气氛。 节目大略步骤为:先用粮食(一般是稻米)在地上"画"出若干级台阶(…

C++语法系列之类型转换

前言 类型转换是经常存在的情况,类型转换分为隐式类型转化 和 显式类型转化 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译失败 double i 3.3; int b i; //隐式类型转化 double -> intC搞出来了四种强制类…

Python----循环神经网络(BiLSTM:双向长短时记忆网络)

一、LSTM 与 BiLSTM对比 1.1、LSTM LSTM(长短期记忆网络) 是一种改进的循环神经网络(RNN),专门解决传统RNN难以学习长期依赖的问题。它通过遗忘门、输入门和输出门来控制信息的流动,保留重要信息并丢弃无关…

工作自动化——工作自动提炼--智能编程——仙盟创梦IDE

工作自动化中的自动提炼、自动比对代码生成日志,为软件开发与项目管理带来诸多好处。 自动提炼能从复杂代码中精准提取关键信息,节省人工梳理时间,开发人员可快速把握核心逻辑,加速项目熟悉进程。自动比对代码则及时发现版本间差异…

运行shell脚本时报错/bin/bash^M: 解释器错误: 没有那个文件或目录

Windows的换行符为\r\n,而linux换行符为\n。先查看一下文件是什么格式的 :set ff --查询一下格式是什么 由于使用nodepad新建的脚本,首选项中格式设置成了windows,上传到linux中报错。 解决方法 1、nodepad中【设置》首选项】修改为unix&am…

6. 基础IO

0.背景 a.访问一个文件,都必须先把对应的文件打开(打开文件就是把它从磁盘加载到内存中) b.如果一个文件,压根就没有被打开,那么它就在磁盘上 c.谁来打开??用户通过bash,启动进程…

碰一碰发视频-源码系统开发技术分享

#碰一碰营销系统# #碰一碰系统# #碰一碰发视频# 架构设计哲学&#xff1a;近场通信的优雅平衡 一、核心通信技术选型 1. 双模协同传输引擎 技术协议栈延迟控制适用场景NFCISO 14443-A<100ms精准触发场景BLE 5.0GATT Profile300-500ms中距传输场景 工程决策依据&…

动态规划之网格图模型(二)

文章目录 动态规划之网格图模型&#xff08;二&#xff09;LeetCode 931. 下降路径最小和思路Golang 代码 LeetCode 2684. 矩阵中移动的最大次数思路Golang 代码 LeetCode 2304. 网格中的最小路径代价思路Golang 代码 LeetCode 1289. 下降路径最小和 II思路Golang 代码 LeetCod…

QUIC——UDP实现可靠性传输

首先我们要知道TCP存在什么样的痛点问题 TCP的升级很困难TCP建立连接的延迟网络迁移需要重新建立连接TCP存在队头阻塞问题 QUIC就是为了解决以上的问题而诞生了, 下面我会介绍QUIC的一些特性和原理 QUIC对比TCP优势: 握手建连更快 QUIC内部包含了TLS, 它在自己的帧会携带TL…

PyTorch——线性层及其他层介绍(6)

线性层 前面1,1,1是你想要的&#xff0c;后面我们不知道这个值是多少&#xff0c;取-1让Python自己计算 import torch import torchvision from torch import nn from torch.nn import Linear from torch.utils.data import DataLoader# 加载CIFAR-10测试数据集并转换为Tensor格…

bilibili批量取消关注

目录 如何使用 ​编辑 代码 如何使用 使用谷歌浏览器&#xff0c;通过F12打开调式面板&#xff0c;找到下面的位置&#xff1a; 代码 /*** 批量取消关注脚本* 自动遍历多页内容并取消所有关注*/// 配置常量 const CONFIG {CLICK_DELAY: 250, // 点击间隔时间&#…

7.RV1126-OPENCV cvtColor 和 putText

一.cvtColor 1.作用 cvtColor 是 OPENCV 里面颜色转换的转换函数。能够实现 RGB 图像转换成灰度图、灰度图转换成 RGB 图像、RGB 转换成 HSV 等等 2.API CV_EXPORTS_W void cvtColor( InputArray src, OutputArray dst, int code, int dstCn 0 ); 第一个参数&#xff1a;…

研发型企业如何面对源代码保密问题

在当今数字化时代&#xff0c;研发团队面临着数据安全和工作效率的双重挑战。技术成果和源代码不仅是企业的核心资产&#xff0c;更是企业竞争力的基石。然而&#xff0c;数据泄露的风险无处不在&#xff0c;从内部员工的无意失误到外部攻击者的恶意窃取&#xff0c;都可能给企…

BeeWorks:私有化即时通讯,筑牢企业信息安全防线

在数字化时代&#xff0c;即时通讯已成为企业日常运营中不可或缺的工具。然而&#xff0c;数据安全问题一直是企业使用即时通讯服务时的重要考量因素。BeeWorks即时通讯系统以其私有化部署模式&#xff0c;为企业提供了一个安全、可靠、自主可控的沟通平台。 私有化部署&#…

akka实践之应用的扩展性问题和actor模型

如何解决应用的扩展性问题 当一个应用需要处理海量并发请求时&#xff0c;传统的开发模式往往显得力不从心&#xff0c;为什么应用需要扩展性&#xff1f; 需求增长: 用户量激增&#xff0c;数据量爆炸式增长。资源限制: 服务器、带宽、存储等资源有限。复杂性增加: 代码逻辑…

Starrocks Full GC日志分析

GC日志样例&#xff1a; [2025-06-03T07:36:06.1770800] GC(227) Pause Full (G1 Evacuation Pause) [2025-06-03T07:36:06.1960800] GC(227) Phase 1: Mark live objects [2025-06-03T07:36:06.9480800] GC(227) Cleaned string and symbol table, strings: 47009 processed,…

mapbox高阶,生成并加载等时图

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️Fill面图层样式1.4 ☘️symbol符号图层…

防火墙在OSI模型中的层级工作(2025)

1. 物理层&#xff08;L1&#xff09;& 数据链路层&#xff08;L2&#xff09; 传统防火墙&#xff1a;通常不处理L1/L2&#xff08;由交换机/网卡负责&#xff09;。 现代演进&#xff1a; MAC地址过滤&#xff1a;部分防火墙支持基于MAC地址的粗粒度策略&#xff08;如禁…