识别和应对内存抖动
关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。
专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。
目录
- 一、导读
- 二、概览
- 三、案例分析
- 3.1 使用memory-profiler
- 3.2 使用 cpu-profiler
- 四、 推荐阅读

一、导读
我们继续总结学习Java基础知识,温故知新。
二、概览
内存抖动是指内存不稳定,频繁分配和回收,导致内存不稳定,其表现形式为频繁GC,
内存抖动可能会导致以下问题:
- 性能下降:由于频繁的内存分配和回收操作,系统的性能会受到影响,导致运行速度变慢。
- 程序崩溃、OOM:内存抖动可能导致内存分配错误或者内存泄漏,导致程序崩溃或者运行不稳定。
- 系统资源消耗:内存抖动会增加系统资源的消耗,包括内存和CPU的占用率,可能导致系统负载增加。
内存抖动大部分都是由于频繁创建对象导致,会占用大量内存,同时会产生大量的内存碎片,不连续的内存碎片很多情况下是无法被分配的。
从而导致OOM的产生。
要防止内存抖动,可以采取以下几个方法和策略:
-
合理规划内存分配:在设计和编写代码时,要合理规划内存的分配和释放,避免频繁的内存分配和回收操作。可以使用对象池、缓冲区等技术来预先分配和管理一块内存,减少内存分配的开销。
-
避免内存碎片:内存碎片是指内存中存在一些被分割成小块的未被使用的空间。内存碎片会导致内存分配失败或效率低下。可以通过使用内存池、内存复用等方法来减少内存碎片的产生。另外,考虑使用内存管理工具或垃圾回收机制来自动进行内存碎片整理和回收。
-
优化算法和数据结构:一些算法和数据结构可能会导致内存抖动,例如频繁的动态数组扩容和收缩操作。可以使用更合适的数据结构或算法,降低内存抖动的概率或频率。比如使用链表代替数组,使用平衡二叉树代替线性查找等。
-
设置适当的内存分配策略:根据实际情况,可以根据内存使用情况和需求,设置合适的内存分配策略。可以使用内存池、内存缓存等技术来预先分配和管理内存,减少频繁的内存分配与回收操作。
-
进行内存性能优化:对于大型或长时间运行的应用程序,可以进行内存性能优化。可以使用内存分析工具和性能分析工具来检测内存使用情况,找出内存抖动的原因,并针对性地进行优化。
-
进行定期的内存测试和性能评估:定期进行内存测试和性能评估,可以发现潜在的内存抖动问题,并进行及时修复和优化。
三、案例分析
不同的工具有不同的使用场景,对应线下场景,我们先用 android studio自带的工具
3.1 使用memory-profiler
可以直观的展示内存使用情况,我们先上一段代码,来模拟内存申请及释放
public class MainActivity extends AppCompatActivity {// Used to load the 'example' library on application startup.static {System.loadLibrary("example");}private static Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);// 循环1000次for (int index = 0; index <= 1000; index++){// 然后弄一个相对耗内存的操作,制造内存抖动String args[] = new String[1000000];}mHandler.sendEmptyMessageDelayed(0,50);}};private ActivityMainBinding binding;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);binding = ActivityMainBinding.inflate(getLayoutInflater());setContentView(binding.getRoot());// Example of a call to a native methodTextView tv = binding.sampleText;tv.setText(stringFromJNI());tv.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mHandler.sendEmptyMessageDelayed(0,2000);}});}/*** A native method that is implemented by the 'example' native library,* which is packaged with this application.*/public native String stringFromJNI();
}
代码运行后,我们进行内存的保存,快速查看Java 和 Kotlin 分配情况分析


通过上面的图,我们可以看到在频繁的gc,
那我们怎么才能知道内存抖动真正发生在哪里呢,看上图,string数组非常多,我们点一下这个string数组,如下图:

上面就出现了一个Call Stack 标签页,显示该实例被分配到何处以及在哪个线程中,我们可以明显的看到 handlemessage,
然后右键选择jump to source,之间跳转到源码查看。
Allocations: 此类创建的实例对象数量
Total count:对象在堆中未被回收的数量
3.2 使用 cpu-profiler
使用方式跟上面差不错,我们保存文件,然后查看,
跟踪这一段CPU执行的时间,
如果发现某一段(应用自有函数的调用)代码(即绿色的条形段)在反复地被执行,便是内存抖动的地方

四、 推荐阅读
Java 专栏
SQL 专栏
数据结构与算法
Android学习专栏

相关文章:
识别和应对内存抖动
关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。 目录 一、导读二、概览三、案例分析3.1 使用memory-profiler3.2 使用 cp…...
3.3用于共享数据保护的替代工具
用于共享数据保护的替代工具 虽然互斥元是最通用的机制,但提到保护共享数据时,它们并不是唯一的选择;还有别的替代品,可以在特定情况下提供更恰当的保护。 一个特别极端(但却相当常见)的情况,…...
探索数据之美:初步学习 Python 柱状图绘制
文章目录 一 基础柱状图1.1 创建简单柱状图1.2 反转x和y轴1.3 数值标签在右侧1.4 演示结果 二 基础时间线柱状图2.1 创建时间线2.2 时间线主题设置取值表2.3 演示结果 三 GDP动态柱状图绘制3.1 需求分析3.2 数据文件内容3.3 列表排序方法3.4 参考代码3.5 运行结果 一 基础柱状图…...
647. 回文子串
boolean默认类型是false class Solution {public int countSubstrings(String s) {if(s null) return 0;int result 0;int length s.length();boolean[][] dp new boolean[length][length];for(int j0;j<length;j){for(int i0;i<j;i){if(s.charAt(i) s.charAt(j)){i…...
cmake (更新中)
概述 关于 CMake CMake 是一个可扩展的开源系统,以一种与操作系统和编译器无关的方式来管理构建过程。与许多跨平台系统不同,CMake 被设计为与本机构建环境配合使用。在每个源代码目录中放置简单的配置文件(称为 CMakeLists.txt 文件…...
【go语言基础】指针数组和数组指针
1.概念 (1)指针数组: 存储指针的数组,也叫存储地址的数组,简单说就是存储地址的。 首先它是一个数组,数组中的元素都是指针(地址)。 (2)数组指针…...
ModaHub魔搭社区——Milvus Cloud向量数据库
向量数据库:在AI时代的快速发展与应用 摘要: 随着人工智能技术的不断进步,向量数据库在处理大规模数据方面发挥着越来越重要的作用。本文介绍了向量数据库的基本概念、应用场景和技术挑战,并详细阐述了Milvus Cloud作为典型的向量数据库产品的技术特点、性能优化和应用案例…...
【Java】常用Stream API
常见 Stream 流表达式 总体结构图 一、两大类型 中间操作(Intermediate Operations) 中间操作是指在Stream上执行的操作, 它们返回一个新的Stream, 允许你链式地进行多个中间操作. 终端操作(Terminal Operations) 对Stream进行最终处理的操作, 当调用终端操作时, Stream会开始执…...
P1941 [NOIP2014 提高组] 飞扬的小鸟
代码部分前有一千六百字了 P1941 [NOIP2014 提高组] 飞扬的小鸟 考察对背包 dp 算法过程理解的透彻性。过程透彻性也是解决所有问题的关键(建立在算法已学的基础上)。 n , m n,m n,m 的范围足够我们 O ( n m ) O(nm) O(nm) 的遍历整个地图。设 f i , …...
Vue3+Element plus+pageHelper实现分页
安装element plus npm install element-plus --save引入 修改main.js: import { createApp } from vue import App from ./App.vue import ElementPlus from element-plus import element-plus/dist/index.cssconst app createApp(App) app.use(ElementPlus) ap…...
外贸路上那些哭笑不得的事情
前几天一个老顾客在软件上联系,说自己上次的订货体验很满意,货物的质量很好,而且服务和回复也很及时, 比起他之前的供货商要好很多,他之前的供货商虽然货物的质量也很好,但是每次询问问题都是要等好久才给…...
双端列表 —— Deque 接口概述,使用ArrayDeque实现队列和双端队列数据结构
Deque接口简介 Deque译为双端队列,在双向都能作为队列来使用,同时可用作栈。Deque接口的方法是对称成比例的。 Deque接口继承Queue接口,因此具有Queue,Collection,Iterable的方法属性。 双端队列的工作原理 在常规队…...
构建可观测架构,从这5个方面着手
随着系统复杂度的提升,“可观测性”(Observability)成为架构建设的重要原则之一。那么构建一个可观测的系统架构需要做哪些工作呢?本文将从以下5个方面介绍构建可观测架构的主要考虑: 1.定义指标和度量,明确关键业务指标需求 首先要确定核心业务指标,比如请求响应…...
前端面试的性能优化部分(7)每天10个小知识点
目录 系列文章目录前端面试的性能优化部分(1)每天10个小知识点前端面试的性能优化部分(2)每天10个小知识点前端面试的性能优化部分(3)每天10个小知识点前端面试的性能优化部分(4)每天…...
【云原生】kubernetes中容器的资源限制
目录 1 metrics-server 2 指定内存请求和限制 3 指定 CPU 请求和限制 资源限制 在k8s中对于容器资源限制主要分为以下两类: 内存资源限制: 内存请求(request)和内存限制(limit)分配给一个容器。 我们保障容器拥有它请求数量的…...
java Long型数据返回到前端失进度问题解决
直接在springmvc配置中增加信息转换。亲测可用。简单粗暴 Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {MappingJackson2HttpMessageConverter jackson2HttpMessageConverter new MappingJackson2HttpMessageCo…...
【设计模式】-策略模式:优雅处理条件逻辑
Java 策略模式之优雅处理条件逻辑 前言 在软件开发中,我们经常会遇到根据不同的条件执行不同逻辑的情况。这时,策略模式是一种常用的设计模式,能够使代码结构清晰、易于扩展和维护。 本文将详细介绍策略模式的概念及其在Java中的应用&#x…...
SpringBoot整合多数据源
SpringBoot整合多数据源 在实际企业项目开发中,我们经常会在SpringBoot项目中配置多数据源,一方面可以减缓数据库压力,另一方面可以也是业务需求的场景 下面就来看看如何在SpringBoot项目中配置多数据源 POM 在配置多数据源之前ÿ…...
CLIP论文精度
CLIP论文精度 Zero-shot CLIP多模态模型 Image Endecoder是一个图片编码器,既可以是ResNet,也可以是Vision Transformer. Text Encoder和Image Encoder产生的两组特征进行对比学习(无监督训练) 分类头?“分类头” 是指网络结…...
LouvainMethod分布式运行的升级之路
1、背景介绍 Louvain是大规模图谱的谱聚类算法,引入模块度的概念分二阶段进行聚类,直到收敛为止。分布式的代码可以在如下网址进行下载。 GitHub - Sotera/spark-distributed-louvain-modularity: Spark / graphX implementation of the distri…...
如何突破抖音视频下载限制:douyin-downloader的全方位解决方案
如何突破抖音视频下载限制:douyin-downloader的全方位解决方案 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallba…...
YOLO11导出TFLite格式:移动端轻量级部署,如何将YOLO11转换为TFLite格式,并测试推理效果全面实战(一)
🎬 Clf丶忆笙:个人主页 🔥 个人专栏:《YOLOv11全栈指南:从零基础到工业实战》 ⛺️ 努力不一定成功,但不努力一定不成功! 文章目录 一、YOLO11与TFLite技术概述 1.1 TFLite格式技术解析 1.2 YOLO11转TFLite的应用价值 二、环境准备与依赖安装 2.1 Python环境配置 2…...
为什么你的.NET 9容器镜像比别人胖47%?——官方SDK分层优化与多阶段构建深度拆解(实测数据支撑)
第一章:为什么你的.NET 9容器镜像比别人胖47%?——问题溯源与性能基线建立当你运行 docker build -t myapp . 构建一个标准的 ASP.NET Core 9 Web API 项目时,镜像大小可能悄然突破 380MB;而采用最佳实践的同类镜像仅约 265MB——…...
Span<T>不是语法糖!透过CoreCLR源码看JIT如何为ref struct生成特殊栈帧——稀缺的底层机制白皮书
第一章:Span<T>不是语法糖!透过CoreCLR源码看JIT如何为ref struct生成特殊栈帧——稀缺的底层机制白皮书Span 是 C# 7.2 引入的 ref struct 类型,它**无法被装箱、不能作为字段存储在托管堆类中、也不允许跨 await 边界捕获**——这些限…...
Linux下Chrony时间同步配置与优化实战
1. 为什么你的服务器需要Chrony时间同步? 想象一下这样的场景:你在银行转账时,交易记录显示的时间比实际时间慢了3秒;或者分布式数据库集群中,不同节点的时间差了0.5秒。这些看似微小的时间差异,轻则导致日…...
128. 如何在 RKE2 或 K3s 集群中更改容器日志级别
Procedure 程序The containerd log level can be set to one of the following values: trace, debug, info, warn, error, fatal or panic. In RKE2 and K3s clusters the log level is not explicitly set by default, and so containerd defaults to info level logging. D…...
上下文工程的学术前沿:最新研究成果与未来发展方向
上下文工程的学术前沿:最新研究成果与未来发展方向 【免费下载链接】Awesome-Context-Engineering 🔥 Comprehensive survey on Context Engineering: from prompt engineering to production-grade AI systems. hundreds of papers, frameworks, and i…...
AI 编程盛行的时代,为什么 “『DC- WFW』” 仍然具有必要性?了
这,是一个采用C精灵库编写的程序,它画了一幅漂亮的图形: 复制代码 #include "sprites.h" //包含C精灵库 Sprite turtle; //建立角色叫turtle void draw(int d){for(int i0;i<5;i)turtle.fd(d).left(72); } int main(){ …...
实战复盘】游戏上市公司合同系统实施案例(六):被忽视的IT力量——为什么业务主导的项目更需要IT深度参与?
本文为《游戏上市公司合同系统实施案例》系列第六篇。 👉 (一)业务背景|(二)多维预算|(三)合同预警|(四)安全攻防|&#x…...
1995-1996 年阿拉斯加北坡 ARCSS/LAII 通量站点的北极植被样地
Arctic Vegetation Plots at ARCSS/LAII Flux Sites, North Slope, Alaska, 1995-1996 简介 本数据集提供了 1995 年和 1996 年 8 月在北坡北极系统科学/陆地-大气-冰相互作用(ARCSS/LAII)项目通量塔站点采集的植被覆盖、环境样地和土壤数据。19 个 AR…...
