Java内存总结

Java之JVM内存结构、Java内存模型、Java对象模型 为什么80%的码农都做不了架构师?>>> ... 阅读详情

一、java内存模型
1.内存模型图形

2.重排序
① 源代码
② 编译器重排序
③ 指令级重排序
④ 内存系统重排序
⑤ 最终执行指令序列
指令级重排序和内存系统重排序,属于处理级重排序。
可能会导致多线程出现内存可见性问题,编译器生成指令,会插入特定类型的内存屏障。
2、volatile内存语义的实现

是否能重排 第二个操作
第一个操作 普通读、写 volatile读 volatile写
普通读、写 YES YES NO
volatile读 NO NO NO
volatile写 YES NO NO
1、当第二个操作是volatile写时,不管第一个操作是什么,都不能重排序。这个规则确 保volatile写之前的操作不会被编译器重排序到volatile写之后。
2、当第一个操作是volatile读时,不管第二个操作是什么,都不能重排序。这个规则确 保volatile读之后的操作不会被编译器重排序到volatile读之前。
3、当第一个操作是volatile写,第二个操作是volatile读时,不能重排序。

1、volatile写之前插入StoreStore屏障;
2、volatile写之后插入StoreLoad屏障;
3、volatile读之后插入LoadLoad屏障;
4、volatile读之后插入LoadStore屏障;
3、锁

在ReentrantLock中,调用lock()方法获取锁;调用unlock()方法释放锁。
ReentrantLock的实现依赖于java同步器框架AbstractQueuedSynchronizer(本文简称之 为AQS)。AQS使用一个整型的volatile变量(命名为state)来维护同步状态,马上我 们会看到,这个volatile变量是ReentrantLock内存语义实现的关键。
4、Final
写final域的重排序规则
禁止把final域的写重排序到构造函数之外。这个规则的实现包含下面2个方面:
1、JMM禁止编译器把final域的写重排序到构造函数之外。
2、编译器会在final域的写之后,构造函数return之前,插入一个StoreStore屏障。这 个屏障禁止处理器把final域的写重排序到构造函数之外。

读final域的重排序规则如下:
1、在一个线程中,初次读对象引用与初次读该对象包含的final域,JMM禁止处理器重排序2、这两个操作(注意,这个规则仅仅针对处理器)。编译器会在读final域操作的前面插入一个LoadLoad屏障。
5、总结
1.jmm内存基本模型

2.Jmm重排序
三个Happen-before:程序顺序性规则、监视器锁规则、volatile规则、传递性。
重排序:编译器重排序、指令级重排序、内存系统重排序。
3.volatile
内存屏障:
volatile写前添加StoreStore屏障;
volatile写后添加StoreLoad屏障;
volatile读后添加LoadLoad屏障;
volatile读后添加LoadStore屏障;
4.final
final读前添加LoadLoad屏障;
final写后添加StoreStore屏障。
final字段不能逃逸构造函数,在访问final字段之前,访问对象之前必须应经被初 始化,初始化对象之前,final字段必须已经被赋值。
5.锁(synchronized、ReentrantLock、concurrent)
AQS中维护一个volatile变量,使用CAS操作内存语义。
二、JVM内存结构
包括:
1、java堆
存储对象,线程共享。OOM
Eden
Old
2、非堆(永久代)
本地方法栈
存储本地方法信息。共有区域。SOF
程序计数器
选择下一条需要执行的字节码指令,分支、跳转、循环等基础功能。私有区域。 OOM
方法区
类型信息(字段、方法)、常量池、静态变量、编译后的代码。共有区域。OOM
JVM栈
栈帧(局部变量表、常量引用、方法返回地址、附加信息、栈计数器),每个方法 调用都创建一个栈帧,该区域是私有的。单线程SOF,多线程OOM。

三、JVM垃圾回收机制
1.垃圾回收算法
标记-清除
标记-(清除)-压缩
复制
增量 分开逐个小区域回收
分代 几个区域不同寿命,一代代回收
并发 停顿
并行 多线程
2、垃圾回收器
年轻代:
Serial:(client模式)
新生代使用复制算法,暂停用户线程;
年老代使用标记整理算法,暂停用户线程;
ParNew:(server模式,多线程版本的Serial收集器)
新生代使用复制算法,暂停用户线程;(多线程)
年老代使用标记整理算法,暂停用户线程;
Parallel Scavenge:(吞吐量优先的收集器)

年老代:
CMS:(响应时间优先(最短回收停顿)的回收器)
使用标记-清除算法
四个阶段:
初始标记
并发标记
重复标记
并发清除

由于CMS会产生浮动垃圾,当回收过后,浮动垃圾如果产生过多,同时因为使用标记-清除算法会产生碎片,可能会导致回收过后的连续空间仍然不能容纳新生代移动过来或者新创建的大资源,因此会导致CMS回收失败,进而触发另外一次FULL GC,而这时候则采用SerialOld进行二次回收。
同时CMS因为可能产生浮动垃圾,而CMS在执行回收的同时新生代也有可能在进行回收操作,为了保证旧生代能够存放新生代转移过来的数据,CMS在旧生代内存到达全部容量的68%就触发了CMS的回收!

Serial Old:(Client)。
年老代使用标记整理算法,暂停用户线程;
Parallel Old:(老生代吞吐量优先的一个收集器)
使用标记整理算法

minorGC:担保GC就是担保minorGC能够满足当前的存储空间,而无需触发老生代的回收,由于大部分对象都是朝生夕死的,因此,在实际开发中这种很起效,但是也有可能会发生担保失败的情况,当担保失败的时候会触发FullGC,但是失败毕竟是少数,因此这种一般是很划算的。

FreeSWITCH编译安装详细文档 本文档详细介绍了在Ubuntu 22.04系统上从源码编译安装FreeSWITCH的完整流程。主要内容包括:1)系统环境准备和依赖库安装;2)关键依赖库spandsp和sofia-sip的编译安装;3)FreeSWITCH源码的特定版本(v1.6.0)编译配置,包括禁用SignalWire模块的配置方法;4)系统服务配置,包括创建专用用户、设置权限以及配置systemd服务文件。文档特别提供了版本控制说明,确保后期能切换到相同的版本环境,并附有详细的命令操作步骤和注意事项。 阅读详情

相关推荐

多租户Saas架构设计分析(基础篇)

本篇先给大家介绍一下相关的概念和常见问题。 实践篇链接:https://blog.youkuaiyun.com/haponchang/article/details/104246317 SaaS简介 SaaS是Software-as-a-Service(软件即服务)的简称,“软件即服务”?是不是有点拗口?其实你就理解成为“按需租用别人提供的软件服务”就可以了,它是一种软件交付模式。...

haponchang的博客 1万+

面试官:说说什么是Java内存模型?

在面试中,面试官经常喜欢问:『说说什么是Java内存模型(JMM)?』面试者内心狂喜,这题刚背过:『Java内存主要分为五大块:堆、方法区、虚拟机栈、本地方法栈、PC寄存器,balabal...

码农小胖哥 1246

手把手教你用RSoft BPM仿真一个1x2光分束器:从参数设置到结果分析全记录

本文详细介绍了使用RSoft BPM模块设计和仿真1×2光分束器的完整流程,包括参数设置、结构建模、仿真配置和结果分析。通过实战指南,帮助读者掌握光波导器件的仿真技术,实现50:50功率分配的设计目标,适用于光通信和集成光学领域的研究与应用。

weixin_30545945的博客 545

java 内存详解_Java内存详解

一、了解java的内存大致划分栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中。堆:存放用new产生的数据静态域:存放在对象中用static定义的静态成员常量池:存放常量二、Java内存分配中的栈在函数中定义的一些基本类型的变量数据和对象的引用变量都在函数的栈内存中分配。当在一段代码块定义一个变量时,Java就在栈中 为这个变量分配内存空间,当该变量退出该作用域后,Jav...

weixin_39943992的博客 1340

CISSP背书三次失败后的终极解决方案

本文分享了作者CISSP认证三次线上背书审核失败的经历与终极解决方案。针对(ISC)²官方审核的严格性,文章详细剖析了使用公积金证明、工作证明盖章签字等常见材料的误区,并最终提出了通过构建“官方邮件往来”证据链的核心策略,以动态、可验证的方式成功通过审核,为后来者提供了详实的避坑指南和实操清单。

weixin_29219539的博客 154

北斗导航 | raPPPid软件功能模块详解

raPPPid(Rapid Precise Point Positioning with integer ambiguity resolution,快速精密单点定位与整周模糊度解算)是由维也纳工业大学(TU Wien)大地测量与地理信息系开发的MATLAB开源PPP软件包。它是VieVS(Vienna VLBI and Satellite Software,维也纳VLBI与卫星软件)的PPP模块,由Marcus Franz Glaner和Robert Weber主导开发。

尘世冰封的专栏 588

java内存结构

------------------------------------------------------术语解答----------------------------------------------------------------------由于在编译过程中并不知道每个类的地址,因为可能这个类还没有加载,所以如果你在一个类中引用了另一个类,那么你完全无法知道他的内存地址,那怎么办,我们只能用他的类名作为符号引用,在类加载完后用这个符号引用去获取他的内存地址。

Small_white_528的博客 955

PostgreSQL核心原理:数据库崩溃恢复的唯一真相详解

PostgreSQL崩溃恢复机制通过WAL日志确保数据一致性和持久性。核心流程包括:触发恢复(非正常关闭时)、读取控制文件获取检查点LSN、顺序扫描WAL日志进行Redo阶段重做已提交事务、利用MVCC标记未提交事务为ABORTED实现逻辑撤销,最后执行检查点完成恢复。该机制依赖WAL原子性、检查点锚点和无Undo的可见性模型三大支柱,保证即使系统崩溃也能恢复到逻辑一致状态。关键设计包括延迟写入、LSN顺序控制和FPW防部分写,最终通过确定性重放实现ACID特性。

数据知道的博客 2664

Java内存区域与Java内存模型

Java内存区域 Java虚拟机在运行程序时会把其自动管理的内存划分为以上几个区域,每个区域都有其用途以及创建销毁的时机,其中蓝色部分代表的是所有线程共享的数据区域,而绿色部分代表的是每个线程的私有数据区域。 方法区(Method Area):方法区属于线程共享的内存区域,又称Non-Heap(非堆),主要用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据,根据...

刚学会HelloWorld的XXX的博客 4458

Mac mini M2 部署 OpenClaw:最稳 7×24 本地 AI 服务器

Mac mini M2 凭借其强大的 M2 芯片、低功耗和静音特性,成为部署 OpenClaw AI 服务器的理想平台。本文详细介绍了从系统配置到 OpenClaw 部署的全过程,包括 Docker 环境搭建、docker-compose 编排、性能优化方案以及开机自启设置。通过统一内存架构和高效 SSD,M2 版 Mac mini 在 AI 推理速度上显著优于前代产品,同时保持极低的功耗(仅 8W),适合 7×24 小时稳定运行。部署方案充分利用了容器化技术,确保了服务的可靠性和可维护性。

一键难忘的博客 2954

Python经典编程习题100例:第25例:求各个阶乘的和

不要自卑,去提升实力 互联网行业谁技术牛谁是爹 如果文章可以带给你能量,那是最好的事!请相信自己 加油o~ 本人初学Python,只为熟悉语法编写,大神请勿理会 点击下面链接 Python经典编程100例习题汇总 题目描述: 求1+2!+3!+…+20!的和。 解题思路: > 调用math模块中的factorial函数 代码: import math sum=0 for i in range(1,21): sum+=math.factorial(i) print(sum) ..

优快云 精品推荐 2736

java 线程 内存_Java 线程究竟占用多少内存

原标题:Java 线程究竟占用多少内存dzone.com/articles/how-much-memory-does-a-java-thread-takeJVM 并没有主动按照线程数量分配 “threads ’ 1MB”,这个错误来自 NMT 报告。Java 8 “committed memory”会自动置为 “reserved memory”。参见 ”committed memory“大小由堆栈...

weixin_34731217的博客 1273

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Java:简述Java内存中的栈内存与堆内存

Java:简述Java内存中的栈内存与堆内存 Java语言把内存划分成两种:一种是栈内存,一种是堆内存。 一、栈内存 栈内存:存放基本类型的变量,对象的引用和方法调用,遵循先入后出的原则。 栈内存,在函数中定义的“一些基本类型的变量和对象的引用变量”都在函数的栈内存中分配。当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配...

王小二(海阔天空) 1226

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

java 堆外内存

堆外内存和堆内内存 堆内内存 java堆内内存,是java虚拟机通过malloc分配后,完全自己管理的,跟操作系统的内存管理没啥区别,java虚拟机有完全的控制权。 java虚拟机通过记录相关信息,能够完全掌握内存的使用情况(有那些空间是剩余的,那一块内存是属于那个对象的),因此通过可达性算法,能够识别出那些内存能够被释放掉。java的GC并不是真正的调用free将内存归还给操作系统,而是将该块内存放入到可用内存列表里面,类似于内存池化。 类似操作系统的内存管理,操作系统也是使用bitmap记录各个内存页的

shuxiaohua的博客 586

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Java内存马使用

对于终端安全:有文件监控、防篡改、EDR;对于后门:有 Webshell 查杀、流量监测;对于网络层面:有防火墙防止反连、反向代理系统隐藏真实 IP;等等。​ 目前主流的防御措施针对 Webshell 的静态检出率在 90% 以上,在部分环境下甚至完全无法落地,防御方可以做到快速应急响应。正因为这些限制,内存马技术得以诞生并快速发展,无文件攻击、内存 Webshell、进程注入等基于内存的攻击手段也受到了越来越多的师傅青睐,在实战环境中已占得一席之地。

mudi13的博客 1813

java 堆内存结构_JAVA之内存结构

概述JAVA是我们现在最常用的开发语言,而他的垃圾回收机制(Garbage Collection)的重要作用不言而喻,以下简称GC,所以了解GC至关重要,现本人对于GC机制以前的理解和现在的理解记录整理一下,供大家参考和指正。说起GC机制,大部分人都把这项技术当做JAVA语言的伴生物。事实上,GC的历史比JAVA久远的多,比如:1960年诞生于MIT的Lisp是第一门真正使用内存动态分配和垃圾收集...

weixin_28756347的博客 1690

Java内存模型和Java内存结构精读

以前看过很多遍JVM相关知识的文章,无非都是直接来张图片开搞,一来就甩张图片上来,这是方法区,这是堆,这是线程独享的一堆堆的概念,看得真的是头大,死记硬背也记不下来,更别说理解了。 最近一段时间在看jvm相关的知识点,这是我唯一一次觉得底层逻辑这么清晰的一次,下面总结一下我的学习心得。 学习jvm之前,一定要先去了解一下cpu的内存模型,如果你连CPU的内存模型都没有了解,直接开干Java的内存模型,什么jvm,垃圾回收啊,劝你别费劲了,死记硬背很快就忘了,我承认确实能记下来,但凭我学习下来的感悟,我觉得我

学习笔记 1160

java 内存问题吗,java 内存问题

java 内存问题今天在网上看到关于对JAVA内存的解释,觉得写的比较好便摘抄下来。在Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点,首先,这些对象是可达的,即在有向图中,存在通路可以与其相连;其次,这些对象是无用的,即程序以后不会再使用这些对象。如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。在C++中,内存泄漏...

weixin_36448411的博客 148

Java深入|JVM内存结构与Java内存模型

1)JVM内存结构; 2)Java内存模型

LJY_Qt的博客 1226

Java内存结构与Java内存模型

Java内存结构、内存模型、对象模型这几个概念经常会被混为一谈。理论知识容易忘写下来帮助记忆,方便以后查看。 1、Java内存结构 Java内存结构其实说的是JVM在运行时内存区域的划分,是根据Java虚拟机规范来实现的。说的是JVM中划分出的各块内存区域分别用来干什么。如上图分为了5大块:方法区,虚拟机栈(有的叫方法栈也有叫线程栈的)、本地方法栈、堆、程序计数器(也有叫寄存器的)。其中方法区和堆是线程共享的内存区域,而虚拟机栈、本地方法栈和程序计数器是线程私有的,或者说是线程隔离的。 1.1 程序计数器

庄北的专栏 1806

Java内存

Java运行时数据区分为五大区块 1、Java虚拟机栈     Java方法执行的内存模型     方法执行的时候同时创建一个栈帧 也就是说这里是用来存储局部变量、方法的地方 2、本地方法栈     Native方法储存位置 3、程序计数器    &...

qq_43360780的博客 226

Java的内存机制

Java的内存机制 Java 把内存划分成两种:一种是栈内存,另一种是堆内存。在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,当在一段代码块定义一个变量时,Java 就在栈中为这个变量分配内存空间,当超过变量的作用域后(比如,在函数A中调用函数B,在函数B中定义变量a,变量a的作用域只是函数B,在函数B运行完以后,变量a会自动被销毁。分配给它的内存会被回收),Jav...

java03_15的博客 2465

java 堆外内存_详解Java堆外内存

临近春节,最近有点时间,准备顺着上篇专栏的思路写下去,建议先阅读:juejin.im/post/684490…武汉那几个吃野味的傻[],请藏好你们的妈正文开始在运行Java程序时,java虚拟机需要使用内存来存放各式各样的数据。java虚拟机规范把这些内存区域叫做运行时数据区:而堆外内存,是指分配在java堆外的内存区域,其不受jvm管理,不会影响gc。本文将以java.nio.DirectByt...

weixin_35794316的博客 1838

java 调内存_java内存设置

最近进入天猫物流做运营支撑,需要在不同系统之间切换来切换去。由于各个系统的规模不一,所以遇到了一下在eclipse里调整VM启动参数的问题,拿出来分享下。JVM启动以后,会分配两类内存区域,一类用于开发人员使用,比如保存一些变量,对象等,一类JVM自己使用,比如存放一些class类和描述。一、第一类内存区域又可以分为栈(stack)、堆(heap),还有一些静态存储区域,这部分的内存在JVM启动的...

weixin_39880623的博客 2450

读取java内存_Java获取可用内存

我最初提供了此示例(链接到威廉·布伦德尔对另一个主题的答案)。该主题的创建者(Steve M)想要创建一个多平台的Java应用程序。具体地说,用户试图找到一种方法来评估运行中的计算机的资源(磁盘空间,CPU和内存使用情况)。这是该主题给出的答案的内联成绩单。但是,尽管我的回答被标记为已接受,但在该主题上已指出这不是理想的解决方案。public class Main {public static v...

weixin_30691649的博客 752

java 内存信息,怎么使用java获取内存信息

当前位置:我的异常网» J2SE»怎么使用java获取内存信息怎么使用java获取内存信息www.myexceptions.net网友分享于:2013-02-26浏览:27次如何使用java获取内存信息?请问如何在windows环境下通过java监控系统内存的使用情况呢?我目前找到两个相关的说明:第一个是下面这个网页http://hi.baidu.com/injava/blog/ite...

weixin_39842475的博客 342
上一篇: Java性能调优笔记
下一篇: nginx+keepalive主从双机热备+自动切换解决方案
wingahi
博客等级 码龄15年 15粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值