当前位置: 首页 > 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; 一、基本情况 这次爬取的方…...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中&#xff0c;手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力&#xff0c;既支持点击、长按、拖拽等基础单一手势的精细控制&#xff0c;也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

【Linux】Linux 系统默认的目录及作用说明

博主介绍&#xff1a;✌全网粉丝23W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换

目录 关键点 技术实现1 技术实现2 摘要&#xff1a; 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式&#xff08;自动驾驶、人工驾驶、远程驾驶、主动安全&#xff09;&#xff0c;并通过实时消息推送更新车…...