Android 性能优化入门(二)—— 内存优化
1、概述
1.1 Java 对象的生命周期
各状态含义:
- 创建:分配内存空间并调用构造方法
- 应用:使用中,处于被强引用持有(至少一个)的状态
- 不可见:不被强引用持有,应用程序已经不再使用该对象了,但是它仍然保存在内存中
- 不可达:GC 运行时检测到(可达性分析)了该对象不再被任何强引用持有,即根不可达
- 收集:被 GC 标记收集准备回收
- 终结:调用该对象的 finalized(),如果 finalized() 内部没有拯救该对象的措施(即便拯救也只能躲过一次 GC),就会执行回收过程
- 对象空间重新分配:对象已经被回收,其占用空间会被重新分配
1.2 JVM 的堆区内存划分示意图
对象在内存区域中流动的大致步骤:
- 对象创建后在 Eden 区
- 执行 GC 后,如果对象仍然存活,则复制到 S0 区
- 当 S0 区满时,该区域存活对象将复制到 S1 区,然后 S0 清空,接下来 S0 和 S1 角色互换
- 当第 3 步达到一定次数(系统版本不同会有差异)后,存活对象将被复制到 Old Generation
- 当这个对象在 Old Generation 区域停留的时间达到一定程度时,最后会移动到 Permanent Generation 区域
Android 系统使用的虚拟机在 JVM 的基础上又会多出几个区域。Dalvik 虚拟机多出:
- Linear Alloc:匿名共享内存
- Zygote Space:Zygote 相关信息
- Alloc Space:每个进程独占
而 ART 虚拟机多出:
- NonMoving Space
- Zygote Space
- Alloc Space
- Image Space:预加载的类信息(预加载是 Zygote 启动过程中执行的任务)
- Large Obj Space:分配大对象的区域,如 Bitmap。
此外还需回忆在 Java 专题中讲过的:
- 可回收对象的判定:不被 GC roots 直接或间接持有的对象是可回收的,GC roots 包括静态变量、线程栈变量、常量池和 JNI(指针)
- Java 的四种引用:强>软(内存不足时回收)>弱(GC 时回收)>虚
- 垃圾回收算法(面试必问):
- 标记清除算法:位置不连续(有内存碎片)、效率略低、两次扫描(第一次标记,第二次回收)
- 复制算法:实现简单、运行高效、没有内存碎片但空间利用率只有一半
- 标记整理算法:没有内存碎片、效率偏低、两次扫描(第一次标记,第二次整理)、指针需要调整
- 分代收集算法:未创建新的算法,只是在不同的内存区域使用以上不同的算法
1.3 app 内存组成与限制
Android 系统给每个 app 分配一个虚拟机 Dalvik/ART,让 app 运行在虚拟机上,即便 app 崩溃也不会影响到系统。系统给虚拟机分配了一定的内存大小,app 可以申请使用的内存大小不能超过此硬性逻辑限制,就算物理内存富余,如果应用超出虚拟机的最大内存就会发生内存溢出。
由程序控制操作的内存空间在堆上,分为 java heapsize 和 native heapsize。Java 申请的内存在 java heapsize 上,如果超过虚拟机的逻辑内存大小就会发生内存溢出的异常;而 native 层的内存申请不受到这个虚拟机的逻辑大小限制,而是受 native process 对内存大小的限制。
通常手机的 RAM 为 4G、8G 甚至 12G,但是每个 app 并不会有太大的内存,通过 adb shell cat /system/build.prop 命令可以看到,虚拟机堆的初始大小为 16M,最大堆内存为 128M:
这个初始大小和最大值,各个手机厂商会自行修改,不同的系统和机型都有可能不同。只不过 Android 系统源码设置的是 16M,在 AndroidRuntime.cpp 中:
int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote){/** The default starting and maximum size of the heap. Larger* values should be specified in a product property override.*/parseRuntimeOption("dalvik.vm.heapstartsize", heapstartsizeOptsBuf, "-Xms", "4m");parseRuntimeOption("dalvik.vm.heapsize", heapsizeOptsBuf, "-Xmx", "16m"); //修改这里}
可以看到给 “dalvik.vm.heapsize” 设置的大小为 16M,可以通过修改这个值改变初始的虚拟机堆大小,也可以通过修改 platform/dalvik/+/eclair-release/vm/Init.c 文件:
gDvm.heapSizeStart = 2 * 1024 * 1024; // Spec says 16MB; too big for us.gDvm.heapSizeMax = 16 * 1024 * 1024; // Spec says 75% physical mem
要获取这个值的话,可以在代码中通过 AMS 获取:
ActivityManager activityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE)activityManager.getMemoryClass(); // 以 m 为单位
其实 AMS 是通过在 AMS.setSystemProcess() 内注册的 meminfobinder 获取到内存信息的,另外 ActivityManager 中还有 MemoryInfo 这个成员。
此外还可以通过 adb shell cat /proc/meminfo 命令查看内存信息:
1.4 Android 的低内存杀进程机制
oom_adj 在讲 AMS 源码时有讲过,可以去复习一下。
AMS 中的 oom_adj 会对应用分级,值为 [-16,15],值越小越不容易被杀,这是一个粗粒度的。此外还有一个 oom_score_adj 评分 [-1000,1000],分越高越容易被杀掉。
通过 adb shell cat /proc/pid/oom_adj 查看 pid 对应的 app 的值,在前台时为 0,按 home 键让其退到后台这个值就会变成 11。如果有两个应用都是 11,那么谁占用的内存大就杀谁,因此【降低应用进入后台后所占用的内存】也是一种保活方法。
1.5 内存三大问题
内存抖动:内存波动图形呈锯齿状,频繁 GC 导致卡顿。
内存泄漏:在当前应用周期内不再使用的对象被 GC Roots 引用,导致不能回收,使实际可使用内存变小。
内存溢出:即 OOM,OOM 时会导致程序异常。Android 设备出厂以后,Java 虚拟机对单个应用的最大内存分配就确定下来了,超出这个值就会 OOM。OOM 可以分为如下基几类:
- Java 堆内存溢出
- 无足够连续内存
- FD 数量超出限制
- 线程数量超出限制
- 虚拟内存不足
2、常见分析内存的命令
2.1 adb shell dumpsys meminfo
输出系统内各个应用占用内存信息,以及分类的内存信息:
按照 oom_adj 排序的信息:
按照文件类型分类的信息:
Total RAM 是总的运行内存,Free RAM 是当前可用内存,Used RAM 是当前已使用的内存。
上图的 PSS 是内存指标概念,与之类似的还有几个,如下表:
Item | 全称 | 含义 | 等价 |
---|---|---|---|
USS | Unique Set Size | 物理内存 | 进程独占的内存 |
PSS | Proportional Set Size | 物理内存 | PSS= USS+ 按比例包含共享库 |
RSS | Resident Set Size | 物理内存 | RSS= USS+ 包含共享库 |
VSS | Virtual Set Size | 虚拟内存 | VSS= RSS+ 未分配实际物理内存 |
其中 VSS >= RSS >= PSS >= USS,但 /dev/kgsl-3d0 部份必须考虑 VSS。
此外还可以通过加 --package 参数查询某个应用的内存情况,如 adb shell dumpsys meminfo --package packageName:
内存优化时可能会用到这个命令(只是大概判断,不是精准判断),比如说在复现前先打印一次内存信息 -> 复现可能的 OOM 操作 -> 再打印一次。
各种其他命令和参数含义去看预习资料 【内存OOM】。
3、常见分析工具
3.1 MAT
按包分类,然后右击选择一个类的 incoming references 和 outgoing references,前者表示持有该类实例的对象,后者表示该类持有哪些类的对象。
浅堆(Shallow Heap)与深堆(Retained Heap):前者只计算自身占用的空间,后者则计算本身以及它所引用的对象那一条链上的所有对象占用的空间。
比如说下图:
A~G 每个对象都占 10 个内存单位,它们的浅堆都是 10,但是 B、C 的深堆就要计算上各自分支上的对象总和,即 30,而 A 要计算分支上所有对象的内存总和,即 70。
此时假如新来一个 H 引用 B,那么这时 A 的深堆变为 40,因为假如把 A 干掉的话,能释放的是 A、C、F、G 这 4 个。新加入的 H 深堆为 10,因为上图中将 H 干掉就只能释放它自己一个对象,不会连带其他对象一起被回收。但是假如在 A 释放后再看 H 的深堆,那么就是 40,因为这个时候释放 H 会实际释放 H、B、D、E 这 4 个对象。
3.2 AS memory profile
看官网连接,介绍的十分详细:
Inspect your app’s memory usage with Memory Profiler
3.3 LeakCanary
LeakCanary 会找出有泄漏嫌疑的对象,并通过 haha 这个开源库进行可达性分析确定是否发生了泄漏。它的使用非常简单,仅需要添加如下依赖:
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.2'
然后如果在应用运行时发生了内存泄漏就会在 UI 上提示我们,还可以保存成 hprof 文件交给 MAT 作进一步分析。
LeakCanary 是如何做到仅添加了一个依赖就帮助应用定位内存泄漏问题的呢?
初始化
首先,在 LeakCanary 的部分模块的 AndroidManifest.xml 中会声明一些 Provider,这些 Provider 在 apk 打包时会汇入 mergeAndroidManifest.xml,最后体现在 app 的 AndroidManifest.xml 文件中。
由于在 AMS 启动过程中,会先执行 ContentProvider 的 onCreate(),后执行 Application 的 onCreate():
LeakCanary 正是利用这一点,在 MainProcessAppWatcherInstaller 中初始化:
/*** Content providers are loaded before the application class is created. [MainProcessAppWatcherInstaller] is* used to install [leakcanary.AppWatcher] on application start.** [MainProcessAppWatcherInstaller] automatically sets up the LeakCanary code that runs in the main* app process.*/
internal class MainProcessAppWatcherInstaller : ContentProvider() {override fun onCreate(): Boolean {val application = context!!.applicationContext as ApplicationAppWatcher.manualInstall(application)return true}
}
监听生命周期
注册 Application.ActivityLifecycleCallbacks 这个生命周期回调来监听 Activity 何时被销毁:
class ActivityWatcher(private val application: Application,private val reachabilityWatcher: ReachabilityWatcher
) : InstallableWatcher {private val lifecycleCallbacks =object : Application.ActivityLifecycleCallbacks by noOpDelegate() {override fun onActivityDestroyed(activity: Activity) {reachabilityWatcher.expectWeaklyReachable(activity, "${activity::class.java.name} received Activity#onDestroy() callback")}}override fun install() {application.registerActivityLifecycleCallbacks(lifecycleCallbacks)}override fun uninstall() {application.unregisterActivityLifecycleCallbacks(lifecycleCallbacks)}
}
ReferenceQueue
LeakCanary 的核心原理是:一个 Reference 对象(一般使用 WeakReference)所引用的对象被 GC 回收时,这个 Reference 对象会被添加到与之关联的(一般通过构造方法关联)引用队列 ReferenceQueue 的队列末尾。以下面代码为例:
public static void main(String[] args) {Object obj = new Object();ReferenceQueue<Object> queue = new ReferenceQueue<>();// 与 ReferenceQueue 关联WeakReference<Object> weakReference = new WeakReference<>(obj, queue);System.out.println("weakReference: " + weakReference);System.out.println("ReferenceQueue: " + queue.poll());obj = null;// Runtime.gc()一定会执行 GC;而 System.gc() 优先级低,调用后也不知何时执行,// 仅仅是通知系统在合适的时间 GC,并不保证一定执行Runtime.getRuntime().gc();try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("weakReference: " + weakReference);System.out.println("ReferenceQueue: " + queue.poll());}
输出为:
weakReference: java.lang.ref.WeakReference@15db9742
ReferenceQueue: null
weakReference: java.lang.ref.WeakReference@15db9742
ReferenceQueue: java.lang.ref.WeakReference@15db9742
可以证明 WeakReference 持有的对象被回收后,该 WeakReference 对象被添加到了与之关联的 ReferenceQueue 的队尾。
LeakCanary 利用这一点去检测可能的内存泄漏,具体步骤为:
- 给每个对象生成一个 uuid,放到观察列表 watchedReferences 中,观察 5 秒
- 5 秒后,调用一次 GC,去 ReferenceQueue 中查找是否有 WeakReference,有说明对象已经被回收,从 watchedReferences 中将其移除。否则该对象没有被回收,则有可能发生内存泄漏,将其添加到怀疑列表 retainedReferences 中
- 当怀疑列表 retainedReferences 中的元素数量大于 5 个时,就交给开源库 haha 去做可达性分析
简版的 LeakCanary 源码分析看视频
4、Bitmap 使用
Bitmap 的内存问题解决好就解决了 90% 的 OOM 问题。基本上加载图片都用的 Glide。不用的话可以参考官网的资料:缓存位图 等等。
Bitmap 解码的 decodeXXX() 最终都会去 native 执行。看看预习资料【内存OOM】。
图片在不同分辨率的设备上的内存中大小可能不一样。当然这是图片放在 xxx-xdpi 中的情况,需要根据公式去算 density。但如果图片来源于网络或者其他不是 xxx-xdpi 文件夹中的情况,density 就是 1。
gradle 可以控制只打包一个维度的 xxx-hdpi 包,不打其他密度的。
解析 Bitmap 的一个技巧:
try {decode bitmap} catch(OutOfMemoryError e) {对 bitmap 进行质量压缩}
加入解析 Bitmap 时发生了 OOM,可以在 catch 中通过质量压缩的方式重新解析该 Bitmap。
第三方开源库 epic 可以 hook ImageView 设置图片的过程,检测图片的质量。
5、总体优化思路
来自于张绍文的 Android 开发高手课。
总体思想:
- 设备分级:
- Bitmap优化
统一图片库
线上线下监控 hook
尽量使用官方推荐的 glide
还可以做一些兜底操作,如果检测到某个 Activity 发生了内存泄漏,那么可以在它的 onDestroy() 中遍历所有成员变量和 View 树并将他们置为 null。
此外在 Activity 中有两个方法 onTrimMemory() 和 onLowMemory(),分别在 App 内存不足和整个设备内存不足时回调,可以在这两个方法中主动释放一些内存。
相关文章:
Android 性能优化入门(二)—— 内存优化
1、概述 1.1 Java 对象的生命周期 各状态含义: 创建:分配内存空间并调用构造方法应用:使用中,处于被强引用持有(至少一个)的状态不可见:不被强引用持有,应用程序已经不再使用该对象…...
(5)python爬虫--BeautifulSoup(bs4)
文章目录 [TOC](文章目录) 前言一、安装bs4二、bs4的基础使用2.1 创建soup对象2.2 根据标签名查找节点2.3 根据函数来查找节点1. find函数2. find_all函数3. select函数 三、使用bs4获取节点信息3.1 获取节点内容3.2 获取节点的属性3.3 获取节点的属性值 四、测试练习 总结 前言…...
如何利用DeepSeek提升工作效率
1. 代码开发辅助 1.1 代码生成 根据需求描述生成代码框架 自动补全代码片段 生成单元测试用例 创建项目文档 1.2 代码优化 代码重构建议 性能优化方案 最佳实践推荐 设计模式应用 2. 问题诊断与解决 2.1 错误分析 编译错误解析 运行时错误诊断 内存泄漏检测 性…...
游戏引擎学习第292天:实现蛇
每次VLC 读取OSD 会有bug 修复一下 回顾并计划实现一种漂浮的移动方式,并制作一个贪吃蛇 虽然不完全记得之前具体计划,但感觉是想实现一个小蛇形生物,之前一直没来得及做。我们还打算让熟悉的伙伴能漂浮移动,所以今天会继续进行一…...
菱形继承原理
在C中,菱形继承的内存模型会因是否使用虚继承产生本质差异。我们通过具体示例说明两种场景的区别: 一、普通菱形继承的内存模型 class A { int a; }; class B : public A { int b; }; class C : public A { int c; }; class D : public B, public C { i…...
C++编程起步项目
员工信息管理系统 需求 Employee.h #pragma once#include<iostream> #include<string>using namespace std;class Employee { public:int id; // 编号string name; // 姓名string position; // 岗位int deptId; // 部门编号Employee();Employee(int id, string n…...
c++编写中遇见的错误
目录 一.获取动态数组的长度二.编译错误三、内存泄露 一.获取动态数组的长度 首先想到获取数组的长度的代码是: sizeof(arr) / sizeof(arr[0]);但是当将其使用到动态数组上时就会产生错误; int* help new int[3];for (int i 0; i < 3; i) {help[…...
股票数据源对接技术指南:印度尼西亚、印度、韩国
一、多国数据对接全景图 1. 核心数据领域对比 国家金融市场数据源宏观经济指标特色数据资源印度NSE/BSE实时行情RBI经济统计库UPI支付数据/GST税务记录印尼IDX交易所数据流BPS官方统计棕榈油产业数据/群岛物流信息韩国KRX综合指数KOSTAT国家统计K-POP消费趋势/半导体出口数据…...
常见面试题:Webpack的构建流程简单说一下。
文章目录 前言一、Webpack 的核心使命:模块化打包二、Webpack 构建流程详解三、构建流程的可视化演示项目结构构建流程图 四、构建流程中的关键技术点1. 依赖图的构建与优化2. 哈希与缓存策略3. 开发环境优化 五、简易版概括构建流程 总结 前言 在前端工程化中&…...
Elasticsearch基础篇-java程序通过RestClient操作es
目录 1.引入 2 初始化RestClient 1)引入es的RestHighLevelClient依赖: 2)因为SpringBoot默认的ES版本是7.17.10,所以我们需要覆盖默认的ES版本: 3)初始化RestHighLevelClient: 4)…...
SuperYOLO:多模态遥感图像中的超分辨率辅助目标检测之论文阅读
摘要 在遥感影像(RSI)中,准确且及时地检测包含数十像素的多尺度小目标仍具有挑战性。现有大多数方法主要通过设计复杂的深度神经网络来学习目标与背景的区分特征,常导致计算量过大。本文提出一种兼顾检测精度与计算代价的快速准确…...
k6学习k6学习k6学习k6学习k6学习k6学习
1.安装go 2.安装 xk6 (k6 扩展构建工具): go install go.k6.io/xk6/cmd/xk6latest3.构建自定义 k6 二进制文件(集成 faker 扩展): xk6 build --with github.com/gkarthiks/xk6-fakerlatest构建报错处理(代码拉取失败)࿱…...
ubuntu 安装mq
一、安装依赖 编译 Erlang 需要以下依赖库和工具: sudo apt update sudo apt install -y build-essential autoconf libncurses5-dev libssl-dev m4 unixodbc-dev libwxgtk3.0-gtk3-dev libgl1-mesa-dev libglu1-mesa-dev 二、解压源码包 tar -xzvf otp_src_21.…...
优化 Spring Boot 应用启动性能的实践指南
1. 引言 Spring Boot 以其“开箱即用”的特性深受开发者喜爱,但随着项目复杂度的增加,应用的启动时间也可能会变得较长。对于云原生、Serverless 等场景而言,快速启动是一个非常关键的指标。 2. 分析启动过程 2.1 启动阶段概述 Spring Boot 的启动流程主要包括以下几个阶…...
ubuntu18.04编译qt5.14.2源码
ubuntu18.04编译qt5.14.2源码 文章目录 ubuntu18.04编译qt5.14.2源码[toc]1 前言2 参考文档3 下载源码3.1 方法13.2 方法23.3 方法3 4 ubuntu编译qt源码4.1 环境准备4.2 设置交换分区大小4.3 编译源码4.4 添加环境变量4.5 验证编译结果4.6 编译帮助文档(qch…...
leetcodehot100刷题——排序算法总结
排序算法总结 冒泡排序介绍步骤(以升序排序为例)算法实现复杂度分析时间复杂度空间复杂度 是否为稳定排序:是稳定排序的定义 选择排序介绍步骤(以升序排序为例)算法实现复杂度分析时间复杂度空间复杂度 是否为稳定排序…...
多用途商务,电子产品发布,科技架构,智能手表交互等发布PPT模版20套一组分享
产品发布类PPT模版20套一组:产品发布PPT模版https://pan.quark.cn/s/25c8517b0be3 第一套PPT模版是一个总结用的PPT封面,背景浅灰色,有绿色叶片和花朵装饰,深绿色标题,多个适用场景和占位符。突出其清新自然的设计和商…...
2025年- H29-Lc137- 19.删除链表的倒数第N个节点(快慢指针)---java版
1.题目描述 2.思路 快慢指针都在虚拟头节点,然后让快指针先走n1步,接下来,快慢指针以前移动,直到快指针指向null,慢指针指向被删节点的前一个节点。 3.代码实现 方法一:不带测试用例 /*** Definition …...
新电脑软件配置二:安装python,git, pycharm
安装python 地址 https://www.python.org/downloads/ 不是很懂为什么这么多版本 安装windows64位的 这里我是凭自己感觉装的了 然后cmd输入命令没有生效,先重启下? 重启之后再次验证 环境是成功的 之前是输入的python -version 命令输入错误 安装pyc…...
医学影像开发的开源生态与技术实践:从DCMTK到DICOMweb的全面探索
🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,10年以上C/C++, C#, Java等多种编程语言开发经验,拥有高级工程师证书;擅长C/C++、C#等开发语言,熟悉Java常用开发技术,能熟练应用常用数据库SQL server,Oracle,mysql,postgresql等进行开发应用…...
【HarmonyOS 5开发入门】DevEco Studio安装配置完全指南
⭐本期内容:【HarmonyOS4+NEXT】Button组件核心特性 🏆系列专栏:鸿蒙HarmonyOS:探索未来智能生态新纪元 文章目录 前言下载开发工具安装开发工具配置开发环境新建项目项目结构概述运行项目Preview预览模拟器运行 报错处…...
出现 Uncaught ReferenceError: process is not defined 错误
在浏览器环境中,process 对象是 Node.js 环境特有的,因此当你在浏览器中运行代码时,会出现 Uncaught ReferenceError: process is not defined 错误。这个错误是因为代码里使用了 process.env.BASE_URL,而浏览器环境下并没有 proc…...
如何实现RTSP和RTMP低至100-200ms的延迟:直播SDK的技术突破
在实时音视频传输中,低延迟是直播应用的核心技术要求之一。无论是在线教育、远程医疗,还是实时互动直播,延迟过大会影响用户体验,甚至导致应用无法正常使用。大牛直播SDK(SmartMediaKit)在RTSP和RTMP播放器…...
linux-----------------库制作与原理(下)
1.ELF文件 要理解编译链链接的细节,我们不得不了解⼀下ELF⽂件。其实有以下四种⽂件其实都是ELF⽂件: • 可重定位⽂件(Relocatable File ) :即 xxx.o ⽂件。包含适合于与其他⽬标⽂件链接来创 建可执⾏⽂件或者共享…...
一种开源的高斯泼溅实现库——gsplat: An Open-Source Library for Gaussian Splatting
一种开源的高斯泼溅实现库——gsplat: An Open-Source Library for Gaussian Splatting 文章目录 一种开源的高斯泼溅实现库——gsplat: An Open-Source Library for Gaussian Splatting摘要Abstract1. 基本思想1.1 设计1.2 特点 2. Nerfstudio&Splatfacto2.1 Nerfstudio2.…...
Embedding 模型详解:架构、训练与 LLM 的区别
1. 什么是 Embedding 模型? Embedding 模型的核心使命是将离散的、高维的文本数据(例如单个词语、短语、句子、段落乃至整篇文档)转化为稠密的 (dense)、低维的 (low-dimensional)、连续的 (continuous) 向量表示。这些向量被称作“嵌入 (Em…...
网络的知识的一些概念
1.什么是局域网,什么是广域网 局域网(Local area network)也可以称为本地网,内网,局域网有这几个发展经历: 最开始电脑与电之间是直接用网线连接的 再后来有了集线器() 再后来出…...
NAT(网络地址转换)逻辑图解+实验详解
原理 NAT(Network Address Translation,网络地址转换) 是一种网络技术,用于在IP数据包通过路由器或防火墙时,修改其源IP地址或目标IP地址,以实现不同网络之间的通信。 基础概念 本来NAT是来解决 IPv4 地…...
深入解析Spring Boot与Kafka集成:构建高性能消息驱动应用
深入解析Spring Boot与Kafka集成:构建高性能消息驱动应用 引言 在现代分布式系统中,消息队列是实现异步通信和解耦的重要组件。Apache Kafka作为一种高性能、分布式的消息系统,被广泛应用于大数据和实时数据处理场景。本文将详细介绍如何在…...
Linux的内存泄漏问题及排查方法
内存泄漏是指在计算机程序中,已不再被使用的内存未被正确释放,导致内存占用随时间累积,进而引发系统内存不足、性能下降甚至崩溃的问题。在Linux系统中,开发者和运维人员可通过以下方法排查和解决内存泄漏问题: 1. 使…...
Java基础知识总结(超详细整理)
一:概述 1.1Java类及类的成员 属性、方法、构造器、代码块、内部类 (1)数组 java虚拟机内存划分 各区域作用 内存解析 基本使用 两个变量指向一个一维数组 没有new就不会在堆里新开辟空间 (2)对象数组 (3&a…...
Qt Widgets模块功能详细说明,基本控件:QPushButton(二)
一、基本控件(Widgets) Qt 提供了丰富的基本控件,如按钮、标签、文本框、复选框、单选按钮、列表框、组合框、菜单、工具栏等。 1、QPushButton 1.1、概述 (用途、继承关系) QPushButton 是 Qt 框架中用于创建按钮的控件,它的主…...
【MySQL成神之路】MySQL常见命令汇总
目录 MySQL常用命令总结 1. 数据库操作 2. 表操作 3. 数据操作(DML) 4. 索引与优化 5. 用户与权限管理 6. 备份与恢复 7. 事务控制 8. 常用函数 9. 系统状态与日志 总结 MySQL常用命令总结 MySQL作为最流行的关系型数据库之一,提供…...
UnLua源码分析(一)初始化流程
UnLua源码分析(一)初始化流程 接入插件启动注册设置默认参数集注册回调SetActivePostLoadMapWithWorldULuaEnvLocator启动Lua虚拟机初始化UE相关的Lua Lib创建与Lua交互的数据结构注册静态导出的类,函数,枚举Lua层初始化 UUnLuaMa…...
非线性1 修改
第一章为读者介绍了非线性动力学与混沌理论的基本概念、发展历史以及应用领域。 1.1 动力学简史: 从牛顿力学开始,介绍动力学作为物理学分支的发展历程。重点介绍了庞加莱对混沌现象的早期探索,以及20世纪60年代洛伦兹方程的发现࿰…...
系统性能不达标,如何提升用户体验?
当系统性能不达标时,要想有效提升用户体验,必须从性能优化、前后端协同、用户感知改善、监控预警机制四个关键维度切入。其中,性能优化是最直接有效的策略,它通过代码优化、资源压缩、缓存机制、CDN加速等手段,显著提升…...
【Linux】进程的基本概念
目录 概念描述进程-PCB如何查看进程通过系统目录进行查看通过ps指令进行查看 通过系统调用获取进程的PID和PPID(进程标⽰符)通过系统调用创建子进程通过一段代码来介绍fork为什么要有子进程?fork为什么给子进程返回0,给父进程返回子进程的PIDfork函数到底…...
mongodb管理工具的使用
环境: 远程服务器的操作系统:centOS stream 9; mongoDB version:8.0; 本地电脑 navicat premium 17.2 ; 宝塔上安装了mongoDB 目的:通过本地的navicat链接mongoDB,如何打通链接,分2步: 第一步:宝塔-&…...
面试中的线程题
原文链接:线程题大全 Java 并发库同步辅助类 CountDownLatch 工作机制:初始化一个计数器,此计数器的值表示需要等待的事件数量。 提供了两个主要方法: await():当一个线程调用此方法时,它将阻塞&#…...
计算机系统的层次结构
计算机系统的层次结构 一, 计算机系统的层次结构的定义 计算机的一个赢软件组成的综合体. 因为面对的应用范围越来越广, 所以必须有复杂的系统软件和硬件的支持. 软/硬件的设计者和使用者从不同的角度, 不同的语言来对待同一个计算机系统, 因此他们看到的计算机系统的属性对计…...
[特殊字符] SSL/TLS 中的密钥协商流程笔记
✅ 背景说明: SSL/TLS 为了确保通信保密性,结合使用了: 非对称加密(用于密钥交换) 对称加密(用于数据加密) 🔁 客户端主导密钥协商的完整流程如下: 1️⃣ 客户端发起…...
多模态大语言模型arxiv论文略读(八十一)
What is the Visual Cognition Gap between Humans and Multimodal LLMs? ➡️ 论文标题:What is the Visual Cognition Gap between Humans and Multimodal LLMs? ➡️ 论文作者:Xu Cao, Bolin Lai, Wenqian Ye, Yunsheng Ma, Joerg Heintz, Jintai …...
SpringBoot(一)--- Maven基础
目录 前言 一、初始Maven 1.依赖管理 2.项目构建 3.统一项目结构 二、IDEA集成Maven 1.Maven安装 2.创建Maven项目 2.1全局设置 2.2 创建SpringBoot项目 2.3 常见问题 三、单元测试 1.JUnit入门 2.断言 前言 Maven 是一款用于管理和构建Java项目的工具ÿ…...
如何使用WordPress创建美食博客
不管你是否意识到,食物是我们生活的核心。有些人将其用作燃料,而另一些人则将食谱作为一种艺术形式呈现。如果您属于后者,并且想创建一个美食博客来分享您的热情,那么WordPress是一个顶级平台。 几乎每个话题都有一个博客利基&am…...
SAP集团内部公司间交易自动开票
SAP集团内部公司间交易自动开票(非STO/EDI模式) 集团内部公司间采购与销售业务,在确认相应单据无误后,为减少人工开票业务, 可以用系统标准功能来实现自动开票。 1.采购发票自动开票(ERS) T-CODE:BP,勾选“基于收货的发票校验”、“自动G…...
代码审计-php框架开发,实战tp项目,打击微交易,源码获取,扩大战果
实战,不安全写法引发的注入 这个bc靶场源码没有,看老师演示 打开很明显的tp框架源码 拿到tp框架之后第一步,搜索版本信息5.0.5 两个思路 1.代码的不安全写法 2.版本自身存在的漏洞 全局搜索where看看也没有不安全的 哎?&…...
Atcoder Beginner Contest 406
比赛链接:ABC406 A - Not Acceptable 将小时转换成分钟直接进行判断。 时间复杂度: O ( 1 ) O(1) O(1)。 #include <bits/stdc.h> using namespace std;int main() {ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);int a,…...
02 K8s双主安装
00 前提准备 # 设置好主机名并添加hosts解析主机名IP地址身份master01172.2.25.50主Mastermaster02172.2.25.51备Masternode01172.2.25.52节点1node02172.2.25.53节点2node03172.2.25.54节点3 01 使用脚本安装Docker # Docker脚本文件 https://node-siyuan.oss-cn-beijing.a…...
分别用 语言模型雏形N-Gram 和 文本表示BoW词袋 来实现文本情绪分类
语言模型的雏形 N-Gram 和简单文本表示 Bag-of-Words 语言表示模型简介 (1) Bag-of-Words (BoW) 是什么? *定义:将文本表示为词频向量,忽略词序和语法,仅记录每个词的出现次数。 **示例: 句子1:I love …...
2_Spring【IOC容器中获取组件Bean】
Spring中IOC容器中获取组件Bean 实体类 //接口 public interface TestDemo {public void doSomething(); } // 实现类 public class HappyComponent implements TestDemo {public void doSomething() {System.out.println("HappyComponent is doing something...")…...