当前位置: 首页 > news >正文

【内存泄漏】内存泄漏及常见的内存泄漏检测工具介绍

内存泄漏介绍

什么是内存泄漏

内存泄漏是指程序分配了一块内存(通常是动态分配的堆内存),但在不再需要这块内存的情况下未将其释放。内存泄漏会导致程序浪费系统内存资源,持续的内存泄漏还导致系统内存的逐渐耗尽,最终导致程序或系统崩溃。

内存泄漏和常驻内存区别

常驻内存(Resident Set)是指进程在运行期间占用的内存大小,包括进程使用的代码、数据和其他资源。常驻内存是进程在运行期间一直驻留在内存中的部分,即使在进程不活动时也不会被释放。
常驻内存通常不会带来显著的负面影响。

程序与进程里的内存布局

下图是源码与 ELF(可执行可链接) 文件以及运行起来后内存布局的简易映射关系图。

程序中的初始化全局变量和局部静态变量被编译到 .data,未初始化的全局变量和局部静态变量编译后放在 .bss 段,代码主体和函数主题存放在 .text 段,ELF 文件内实际有很多段(参考《程序员的自我修养-链接,装载与库》第三章)。
当程序运行时,会将 ELF 文件加载到内存。不同的段会加载到内存布局中的不同位置,其中 heap 这部分就是程序员手动去动态申请和释放内存的部分。当程序员用 malloc 函数申请了一块内存,使用完之后却没有 free 它的时候,就会发生内存泄漏。内存泄漏得越多,进程中可以使用内存的空间就越少,时间长了就会导致系统响应慢,甚至程序崩溃。

如何“观察”内存泄漏是否发生?

在 Android 系统上通常可以用 dumpsys meminfo 命令查看进程的内存使用数据,重复 dump 后从数据的变化情况来大致判断是否有内存泄漏。

也可以借助python 或者其他一些工具将数据可视化方便查看数据变化趋势。

但这只能大致的给你展示数据变化的趋势,而非直接明白的告诉你是否发生了内存泄漏。因此我们需要更精确的工具来检测是否也有内存泄漏。

常见的内存检测工具介绍

本节我们将依次介绍 Malloc Debug, libmemunreachable, Asan, HwASan, MTE, Heapprofd, Memcheck(Valigrind)
内存泄漏检测工具(https://source.android.com/docs/core/tests/debug/native-memory?hl=zh-cn)

Malloc Debug

简介

Malloc Debug 是一种调试本机内存问题的方法。 它可以帮助检测内存损坏、内存泄漏和释放后使用问题。
Malloc Debug 通过对常规的 allocation 函数包装了一层来记录和分析内存的申请和释放。这些函数包括:malloc, free, calloc, realloc, posix_memalign, memalign, aligned_alloc, malloc_usable_size

使用方法

运行程序前的设置

adb shell setprop libc.debug.malloc.options "\"backtrace guard leak_track backtrace_dump_on_exit backtrace_dump_prefix=/sdcard/heap"\"
adb shell setprop libc.debug.malloc.program xxx(进程名)

参数介绍:

  • backtrace: 开启堆栈记录。
  • guard: 开启内存越界检测。
  • leak_track: 程序在退出时,如有内存泄漏,而不产生abort。
  • backtrace_dump_on_exit: 程序退出时dump堆栈和内存信息。
  • backtrace_dump_prefix: dump文件存放的路径和文件名的开头字符。如本处生成的文件放在/sdcard/目录下,文件名开头为heap字样,注意指定的路径要有写权限。
  • libc.debug.malloc.program: 用于设置检测的程序,不设置则检测所有的运行的程序。

执行待测试程序

  1. 离线程序
    离线程序运行完成后会在 backtrace_dump_prefix 设定的路径下存储 dump 文件
  2. 在线程序
    需要先停掉程序所在的进程,再重启该进程才会生效。
    由于在线程序一般不会主动退出(如 camerahalserver),需要使用命令来主动触发 dump。
    命令:kill -47 xxx(进程ID),注意多次触发新文件覆盖之前的文件。
    当你的程序有内存泄漏问题的话,输出如下报告:
E malloc_debug: +++ memtest leaked block of size 48 at 0x7a4a6a42e0 (leak 1 of 2)
E malloc_debug: Backtrace at time of allocation:
E malloc_debug:           #00  pc 000000000004461c  /apex/com.android.runtime/lib64/bionic/libc.so (malloc+76)
E malloc_debug:           #01  pc 00000000000c83e8  /apex/com.android.runtime/lib64/bionic/libc.so (__register_atfork+40)
E malloc_debug:           #02  pc 000000000005460c  /apex/com.android.runtime/lib64/bionic/libc.so
E malloc_debug:           #03  pc 00000000000613a0  /apex/com.android.runtime/bin/linker64
E malloc_debug:           #04  pc 0000000000061144  /apex/com.android.runtime/bin/linker64
E malloc_debug:           #05  pc 0000000000061144  /apex/com.android.runtime/bin/linker64
E malloc_debug:           #06  pc 00000000000d5f14  /apex/com.android.runtime/bin/linker64
E malloc_debug:           #07  pc 00000000000d4e0c  /apex/com.android.runtime/bin/linker64
E malloc_debug:           #08  pc 0000000000064004  /apex/com.android.runtime/bin/linker64
E malloc_debug: +++ memtest leaked block of size 20 at 0x793a6ae9a0 (leak 2 of 2)
E malloc_debug: Backtrace at time of allocation:
E malloc_debug:           #00  pc 000000000004461c  /apex/com.android.runtime/lib64/bionic/libc.so (malloc+76)
E malloc_debug:           #01  pc 00000000000100b8  /data/local/tmp/memtest/memtest
E malloc_debug:           #02  pc 00000000000546e8  /apex/com.android.runtime/lib64/bionic/libc.so (__libc_init+104)
E malloc_debug: Dumping to file: /sdcard/heap.19748.exit.txt

注意报告中并不是所有的 leak 都是真正的内存泄漏,有些可能是常驻内存,开发者需要自己判断。
还需注意dump 路径要有写权限

很多时候在线运行环境下so 是无符号的程序,我们需要解析 dump 文件定位代码行号
python3 native_heapdump_viewer.py --symbols ./symboldir/ ./heap.4169.exit.txt --html > memtest4169.html

–symbols 指定的是符号库/程序的路径,子目录的路径必须要在手机上的路径一致。比如可执行程序在手机里的路径是/vendor/bin/memtest,那解释时它的带符号的程序路径上需要是 ./symboldir/vendor/bin/memtest

检测出来的并不是都是泄漏,一部分是属于常驻内存,尤其对于在线程序,我们需要将程序运行不同的次数,抓出不同的log来做对比,找出真正增长的部分。

libmemunreachable

简介

Android 的 libmemunreachable 是一个零开销的本地内存泄漏检测器。 它会在触发内存检测的时候遍历进程内存,同时将任何不可访问的块报告为泄漏。

命令行方式使用

设置属性

adb root
adb shell setprop libc.debug.malloc.program app_process
adb shell setprop wrap.[process] "\$\@“
adb shell setprop libc.debug.malloc.options backtrace=4

参数

  • backtrace_size 只收集泄漏指定 size 大小的 backtrace
  • backtrace_min_size=192 backtrace_max_size=320 收集泄漏 size 介于两者之间的backtrec

重启应用,执行 dumpsys -t 600 meminfo --unreachable [process].(自测没有 dump 出预期结果)。下面是一个带有内存问题的输出结果。

 Unreachable memory24 bytes in 2 unreachable allocationsABI: 'arm64'24 bytes unreachable at 71d37787d0first 20 bytes of contents:71d37787d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................71d37787e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................24 bytes unreachable at 71d37797d0first 20 bytes of contents:71d37797d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................71d37797e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

添加代码方式使用

官方提供4个接口来检测内存
C interface

  • bool LogUnreachableMemory(bool log_contents, size_t limit)
  • bool NoLeaks()

C++ interface

  • bool GetUnreachableMemory(UnreachableMemoryInfo& info, size_t limit = 100)
  • std::string GetUnreachableMemoryString(bool log_contents = false, size_t limit = 100)

核心函数是 GetUnreachableMemory() 其他三个函数内部都会调用此函数。
在使用添加代码的方式打印时,需要在编译代码时需要将 libmemunreachable.so 添加到动态依赖,libmemunreachable.so 文件可以在手机 /system/lib64/libmemunreachable.so 获取。

例子:
以下是一个包含内存泄漏的例子,在f 函数中申请了x, y 两块内存,在函数返回前x 被释放,y 赋值后没有被释放。

#include "./memunreachable.h"#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>using namespace android;void f(void);
void f(void) {printf("[memtest] function f\n");int* x = (int*)malloc(10 * sizeof(int));x[0] = 0;int* y = (int*)malloc(5 * sizeof(int));y[0] = 0;y[1] = 1;y[2] = 2;y[3] = 3;y[4] = 4;free(x);
}int main(void) {printf("[memtest] hello main\n");f();// C interfaceprintf("LogUnreachableMemory()\n");LogUnreachableMemory(true, 100);return 0;
}

adb log 输出(考虑排版省去时间戳)
log 里显示有一个 20 bytes 的内存泄漏,20 正是5 个 int 的大小,对应申请但没有释放的 y 地址的内存。

// 新建 Collection process
31232 31231 I libmemunreachable: collecting thread info for process 31231...
31232 31231 I libmemunreachable: collection thread done
// fork 进程运行 sweeping process 
31233 31233 I libmemunreachable: searching process 31231 for allocations
31233 31233 I libmemunreachable: searching done
31233 31233 I libmemunreachable: sweeping process 31231 for unreachable memory
31233 31233 I libmemunreachable: sweeping done
31233 31233 I libmemunreachable: folding related leaks
31233 31233 I libmemunreachable: folding done
// 回到 Original process 接收检测结果
31231 31231 I libmemunreachable: unreachable memory detection done
31231 31231 E libmemunreachable: 20 bytes in 1 allocation unreachable out of 1260 bytes in 7 allocations
31231 31231 E libmemunreachable:   20 bytes unreachable at 7a03454400
31231 31231 E libmemunreachable:    contents:
31231 31231 E libmemunreachable:    7a03454400: 00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 ................
31231 31231 E libmemunreachable:    7a03454410: 04 00 00 00                                     ....
31231 31231 E libmemunreachable:           #00  pc 000000000003e238  /apex/com.android.runtime/lib64/bionic/libc.so (malloc+84)
31231 31231 E libmemunreachable:           #01  pc 00000000000100b8  /data/local/tmp/memtest/memtest_libmemunreachable
31231 31231 E libmemunreachable:           #02  pc 000000000004aa48  /apex/com.android.runtime/lib64/bionic/libc.so (__libc_init+100)

调用 bool LogUnreachableMemory(bool log_contents, size_t limit) 时,log_contents 传 true 会打印泄露地址的内容,也就是 contents 对应的两行内容。之后可以用 address2line 解析行号。

其他内存检测工具简介

ASan

  • Asan(AddressSanitizer) 适用于检测内存越界访问、缓冲区溢出、内存泄漏等问题。它是一个在编译时插入的工具;
  • 运行时有一定的性能开销(约增加两倍),代码大小和内存均有额外开销;
  • 需要重新编译程序,编译时添加 address 相关选项;
  • 可用于 linux 和 android,但在 android 上逐步被 HwASan 取代;
  • 需要刷与 ASan 兼容的 ROM;
  • 不再受支持,即使有bug 也不会修复;

HWASan

  • HWASan 利用硬件特性,适用于检测内存错误,类似于 ASan,但能够更高效地运行在一些支持硬件特性的平台上。
  • 性能开销和 Asan 接近,但内存占用更小;
  • 需要重新编译程序,编译时添加 hwaddress 相关选项
  • 仅适用于 Android 10 及更高版本,AArch64 硬件;
  • 需要刷与 HWASan 兼容的 ROM;

MTE

  • MTE(Memory Tagging Extension) 使用硬件标签来检测内存错误,主要专注于检测内存越界访问。
  • 提供了较低的性能开销,首次具备了线上部署的可能。
  • 无需重新构建代码来检测堆错误(但需要重新构建代码来检测堆栈错误)
  • Android 系统在 Arm v9 上开始支持,仅适用于64位应用/程序;

Heapprofd

  • Heapprofd 是一个跟踪给定时间段内 Android 进程的堆分配和释放的工具。
  • 可以借助 Perfetto 抓取,开发人员可以使用该工具调查内存问题(调用栈和内存分配)。

    当开启连续 dump 后,开发者可以查看程序结束前内存占用是否合理,以检查是否有潜在内存泄漏问题。或者将待测试代码循环执行,比较每执行一次代码段后内存是否有增加,一次判断是否有内存泄漏。

Valgrind 中的Memcheck

  • Memcheck 是 Valgrind 工具套件中的一个工具,用于检测 C 和 C++ 程序中的内存错误。
  • 内存问题检测比较全面,但对性能影响比较大,耗时增加10x~20x,不适用对时间敏感的程序。
  • 在 Ubuntu 上安装:sudo apt-get install valgrind

使用 memcheck 的基本方法

  • 编译程序时加上 –g 选项,编译优化选项建议选择 -O1;
  • 使用 Valgrind 命令运行程序:valgrind --leak-check=yes myprog arg1 arg2valgrind 使用 --tools 来指定 debug 工具,而 Memcheck 是默认工具,可以省略 --tools=memcheck 选项;
  • 程序运行后输出问题报告。
$ valgrind --leak-check=yes ./memtest_origin 
==19517== Memcheck, a memory error detector
==19517== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==19517== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==19517== Command: ./memtest_origin
==19517== 
[memtest] hello main
[memtest] function f
==19517== 
==19517== HEAP SUMMARY:
==19517==     in use at exit: 20 bytes in 1 blocks
==19517==   total heap usage: 3 allocs, 2 frees, 1,084 bytes allocated
==19517== 
==19517== 20 bytes in 1 blocks are definitely lost in loss record 1 of 1
==19517==    at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==19517==    by 0x1086FF: f() (memtest_origin.cc:9)
==19517==    by 0x108731: main (memtest_origin.cc:16)
==19517== 
==19517== LEAK SUMMARY:
==19517==    definitely lost: 20 bytes in 1 blocks
==19517==    indirectly lost: 0 bytes in 0 blocks
==19517==      possibly lost: 0 bytes in 0 blocks
==19517==    still reachable: 0 bytes in 0 blocks
==19517==         suppressed: 0 bytes in 0 blocks
==19517== 
==19517== For counts of detected and suppressed errors, rerun with: -v
==19517== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

总结

本文我们介绍了内存泄漏的概念,malloc debug 和 libmemunreachable 的使用方法,以及一些其他内存检测工具的简介,下一篇我们将介绍 malloc debug 和 libmemunreachable 的工作原理。

参考链接

  1. 【内存】Android C/C++ 内存泄漏分析 unreachable
  2. 调试本地内存使用  |  Android 开源项目  |  Android Open Source Project
  3. 调试和减少内存错误  |  Android NDK  |  Android Developers (google.cn)
  4. Malloc Debug (googlesource.com)
  5. Malloc Hooks (googlesource.com)
  6. libmemunreachable (googlesource.com)
  7. Memcheck: a memory error detector
  8. Heap profiler - Perfetto Tracing Docs

相关文章:

【内存泄漏】内存泄漏及常见的内存泄漏检测工具介绍

内存泄漏介绍 什么是内存泄漏 内存泄漏是指程序分配了一块内存&#xff08;通常是动态分配的堆内存&#xff09;&#xff0c;但在不再需要这块内存的情况下未将其释放。内存泄漏会导致程序浪费系统内存资源&#xff0c;持续的内存泄漏还导致系统内存的逐渐耗尽&#xff0c;最…...

FPGA-ZYNQ-7000 SoC在嵌入式系统中的优势

FPGA-ZYNQ-7000 SoC在嵌入式系统中的优势 本章节主要参考书籍《Xilinx Zynq-7000 嵌入式系统设计与实现 基于ARM Cortex-A9双核处理器和Vivado的设计方法 (何宾&#xff0c;张艳辉编著&#xff09;》 本章节主要讲述FPGA-ZYNQ-7000 SoC在嵌入式系统中的优势&#xff0c;学习笔…...

如何在Vue3中实现无缝热重载:提升你的开发效率

Vue3中的热重载&#xff08;Hot Module Replacement&#xff0c;简称HMR&#xff09;是一种开发时的功能&#xff0c;它允许开发者在不刷新整个页面的情况下&#xff0c;实时替换、添加或删除模块。这意味着当你对Vue组件进行修改并保存时&#xff0c;这些更改会立即反映在浏览…...

盒子 Box

UVa1587 思路&#xff1a; 1.输入每个面的长宽并将每个面较长的一边放在前面 2.判断是否存在三对面分别相等 3.判断是否存在三组四棱相等 #include <stdio.h> #include <stdlib.h> #define maxn 100int cmp(const void* e1, const void* e2) {return (int)(*(d…...

uni-app附件下载预览 并解决打开附件时黑屏

// 预览附件perviewFile(file) {console.log(点击附件, file)var strfile.previewUrlvar filTypestr.split(.)console.log(filType,filType)uni.downloadFile({url: success: function(res) {console.log(打开文档成功, res);if (res.statusCode 200) {uni.saveFile({tempFile…...

卸载了Visual Studio后,在vscode中执行npm i或npm i --force时报错,该怎么解决?

卸载了Visual Studio后&#xff0c;在vscode中执行npm i或npm i --force时报错,该怎么解决&#xff1f; 报错内容&#xff1a;原因解决办法 报错内容&#xff1a; npm ERR! code 1 npm ERR! path E:\VScode\codeDate\yugan\node_modules\node-sass npm ERR! command failed np…...

渗透测试 | 信息收集常用方法合集

目录 一、关于域名 1.子域名收集 a.搜索引擎查找 b.在线查询 c.工具 d.SSL/TLS证书查询 2.端口型站点收集 3.目录文件扫描 a.目录扫描工具 b.github搜索 c.google搜索 d.在线网站 e.文件接口工具 4.旁站和C段 a.旁站查询 b.C段查询 5.网站技术架构信息 a.基础…...

使用 ElementUI 组件构建无边框 Window 桌面应用(WinForm/WPF)

生活不可能像你想象得那么好,但也不会像你想象得那么糟。 我觉得人的脆弱和坚强都超乎自己的想象。 有时,我可能脆弱得一句话就泪流满面;有时,也发现自己咬着牙走了很长的路。 ——莫泊桑 《一生》 一、技术栈 Vite + Vue3 + TS + ElementUI(plus) + .NET Framework 4.7.2…...

JavaScript中数组的方法和函数作用域问题

1 -函数作用域问题-: 函数的外层作用域&#xff0c;在函数创建时就已确定&#xff0c;和函数的调用位置无关 var name 嘿嘿;// 函数的外层作用域&#xff0c;在函数创建时就已确定&#xff0c;和函数的调用位置无关// JS中的作用域被称为 词法作用域function fn() {console.…...

nodejs设置x-xss-protection解决xss问题

在Node.js中设置X-XSS-Protection可以通过使用helmet库来完成。 首先&#xff0c;确保已经安装了helmet库。如果没有安装&#xff0c;可以运行以下命令进行安装&#xff1a; npm install helmet --save 然后&#xff0c;在你的Node.js应用程序中引入并配置helmet库&#xff…...

C/C++不同整数类型的区别

在C/C中涉及的整数相关的类型大致有如下几种&#xff1a; char、unsigned charshort、unsigned shortint、unsigned intlong、unsigned longlong long、unsigned long longint8_t、uint8_tint32_t、uint32_tint64_t、uint64_tDWORDDWORD32、DWORD64size_t、ssize_tSIZE_T、SSI…...

如何理解JDK、JRE、JVM区别与联系

摘要&#xff1a;JDK是 Java 语言的软件开发工具包(SDK)。在JDK的安装目录下有一个jre目录&#xff0c;里面有两个文件夹bin和lib&#xff0c;在这里可以认为bin里的就是jvm&#xff0c;lib中则是jvm工作所需要的类库&#xff0c;而jvm和 lib合起来就称为jre。 一、JDK JDK(Ja…...

用友GRP-U8 SmartUpload01 文件上传漏洞

漏洞描述 用友GRP-U8行政事业内控管理软件是一款专门针对行政事业单位开发的内部控制管理系统&#xff0c;旨在提高内部控制的效率和准确性。该软件/u8qx/SmartUpload01.jsp接口存在文件上传漏洞&#xff0c;未经授权的攻击者可通过此漏洞上传恶意后门文件&#xff0c;从而获取…...

react 路由v6

这里是区别&#xff1a;V5 vs V6 这里是官网&#xff1a;可以查看更多高级属性 一、基本使用&#xff1a; 1、配置文件 src/routes/index import React from "react";const Home React.lazy(() > import("../Pages/Home")); const About React.laz…...

rpc【通义】rpc原理【gpt】

一 rpc RPC&#xff08;Remote Procedure Call&#xff0c;远程过程调用&#xff09;是一种编程技术&#xff0c;它允许在分布式系统中的一个程序像调用本地函数一样调用另一个程序&#xff08;位于不同的机器或进程中&#xff09;的函数或方法。RPC的主要目标是隐藏网络通信的…...

Leetcode 2973. Find Number of Coins to Place in Tree Nodes

Leetcode 2973. Find Number of Coins to Place in Tree Nodes 1. 解题思路2. 代码实现 题目链接&#xff1a;2973. Find Number of Coins to Place in Tree Nodes 1. 解题思路 这道题思路上其实挺简单的&#xff0c;就是一个遍历的思路&#xff0c;找到每一个点对应的子树当…...

如何调动销售人员使用CRM的积极性?

CRM系统在销售人员眼中是流程监管工具也是单调枯燥的操作空间&#xff0c;如何让销售爱上CRM系统&#xff1f;1.让CRM简化销售工作&#xff1b;2.智能提醒销售各项事务&#xff1b;3.让CRM界面更加丰富多彩&#xff0c;通过这些方法帮助销售经理轻松管理团队&#xff0c;销售对…...

数值分析期末复习

第一章 科学计算 误差 解题步骤 x : 真实值 x:真实值 x:真实值 x ∗ : 近似值 x^*:近似值 x∗:近似值 先求绝对误差 e ∗ e^* e∗: x − x ∗ x - x^* x−x∗ 绝对误差限是 ∣ x − x ∗ ∣ ≤ ε |x - x^{*}| \le \varepsilon ∣x−x∗∣≤ε 求相对误差限: ∣ x − x ∗…...

k8s的探针

一、探针原理 分布式系统和微服务体系结构的挑战之一是自动检测不正常的应用程序&#xff0c;并将请求&#xff08;request&#xff09;重新路由到其他可用系统&#xff0c;恢复损坏的组件。健康检查是应对该挑战的一种可靠方法。使用 Kubernetes&#xff0c;可以通过探针配置运…...

Python 爬虫之下载视频(五)

爬取第三方网站视频 文章目录 爬取第三方网站视频前言一、基本情况二、基本思路三、代码编写四、注意事项&#xff08;ffmpeg&#xff09;总结 前言 国内主流的视频平台有点难。。。就暂且记录一些三方视频平台的爬取吧。比如下面这个&#xff1a; 一、基本情况 这次爬取的方…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

MyBatis中关于缓存的理解

MyBatis缓存 MyBatis系统当中默认定义两级缓存&#xff1a;一级缓存、二级缓存 默认情况下&#xff0c;只有一级缓存开启&#xff08;sqlSession级别的缓存&#xff09;二级缓存需要手动开启配置&#xff0c;需要局域namespace级别的缓存 一级缓存&#xff08;本地缓存&#…...