android 如何分析应用的内存(八)——malloc debug

news2024/11/23 7:42:29

android 如何分析应用的内存(八)

接上文,介绍六大板块中的第三个————malloc调试和libc回调

上一篇文章中,仅仅是在分配和释放的时候,拦截对应的操作。而不能进一步的去检查内存问题。比如:释放之后再次使用指针,内存泄漏,内存损坏等等。

在这篇文章中,将会介绍malloc调试技术,它可以对native的内存,进行更加细致的检测,并且可以支持到Android 4.4 。而malloc hook最低也只能支持到Android 9.0.

但从Android 7.0以后有一个改版。因此将分两部分进行介绍。第一部分先介绍Android 7.0之后的malloc 调试,第二部分介绍Android 7.0之前的malloc 调试

malloc debug原理简述

在前面两篇文章中,我们分别实现了

  1. 自定义的分配函数,
  2. 拦截分配函数

然后在每次分配的时候,保存对应的堆栈信息,而在释放的时候,删除掉这些堆栈信息。

现在,我们可以脱离这些束缚,直接让malloc内部的功能来实现。bionic库自己增加了一层shim层。shim层会替换下面的这些函数的调用。从而达到内存debug的目的。

void* malloc(size_t __byte_count) ;
void free(void* __ptr);
void* calloc(size_t __item_count, size_t __item_size) ;
void* realloc(void* __ptr, size_t __byte_count) ;
int posix_memalign(void **memptr, size_t alignment, size_t size);
void* memalign(size_t __alignment, size_t __byte_count) ;
void *aligned_alloc(size_t alignment, size_t size);
size_t malloc_usable_size(const void* __ptr) ;

在32位系统各种,下面两个函数也会被替换

void *pvalloc(size_t size);
void *valloc(size_t size);

shim层的技术细节有:

  1. 记录内存分配:当调用malloc时,bionic自动记录调用的堆栈,以及其他的一些调试信息。
    当调用free的时候,则会检测这些调试信息,看看是否有错误
  2. 填充内存:当分配和释放的时候,会用特定的bit位来填充内存。如分配新内存,用0xaa填充。free之后,用0xbb填充。这样可以检测到未初始化的内存和使用已经free之后的内存错误。
  3. 增加guard区域:在分配内存的时候,会在内存的头尾,增加一小段guard区域。称为保护区域。他们被填充为特殊的bit位。在内存被释放的时候,会检查这些区域是否被修改。如果被修改,则说明存在越界的问题
  4. 内存泄漏检测:当程序结束的时候,就会检测所有未被释放的内存,如果存在未被释放的内存,就将调用栈打印到log系统中。便于定位源头

Android 7.0以后的malloc debug如何启用

对于Android APP工程师

只需要给环境变量LIBC_DEBUG_MALLOC_OPTIONS赋予不同的值,即打开不同的功能。如下:
两种方式,通过wrap.<APP>和wrap.sh。这两种方式的说明,见上一篇文章android 如何分析应用的内存(七)

现在,描述如下:

adb shell setprop wrap.<APP> '"LIBC_DEBUG_MALLOC_OPTIONS=backtrace logwrapper"'
## wrap.<APP>的介绍,见上一篇文章

wrap.sh内容如下:

#!/system/bin/sh
export LIBC_DEBUG_MALLOC_OPTIONS=backtrace\ leak_track\ fill
## 注意,当要使能多个选项的时候,空格符前面有一个斜杠转义符
exec "$@"

上面的backtrace,leak_track,fill的具体含义,见后文介绍。

如果打开成功,在log中会有如下的输出

malloc debug enabled

在这里插入图片描述

注意:如果你的设备是Android 12。那么在Android 12上有一个bug,这个bug会导致wrap.app属性无法正常工作,为了在Android 12的设备上能够让wrap.app属性正常工作,需要添加如下代码

adb shell setprop dalvik.vm.force-java-zygote-fork-loop true
adb shell stop
adb shell start

再次注意:在Android 8.0以前,属性的名字字符串长度不能超过32个字符。因此当包名太长的时候,就不得不将包名改短

对于Android Framework工程师

可以通过下面的办法,打开所有应用的backtrace记录

## 停止系统服务
adb shell stop
## 打开对应功能
adb shell setprop libc.debug.malloc.options backtrace
## 启动系统服务
adb shell start

还可以指定的进程,设置,如下:

## 打开backtrace功能
adb shell setprop libc.debug.malloc.options backtrace
## 指定程序为ls
adb shell setprop libc.debug.malloc.program ls
## 运行ls
adb shell ls

还可以为zygote,和基于zygote的进程设置,比如,应用程序。如下:

## 停止系统服务
adb shell stop
## 设置进程名字
adb shell setprop libc.debug.malloc.program app_process
## 打开backtrace功能
adb shell setprop libc.debug.malloc.options backtrace
## 启动系统服务
adb shell start

再比如,同时打开多个功能

adb shell stop
## 同时打开多个功能,注意,双引号
adb shell setprop libc.debug.malloc.options "\"backtrace guard\""
adb shell start

注意:有两个双引号

除了上面通过系统属性以外,还可以通过环境变量。

Android 8.0以前

可以通过如下方法:

adb shell
# setprop libc.debug.malloc.env_enabled 1
# setprop libc.debug.malloc.options backtrace
# export LIBC_DEBUG_MALLOC_ENABLE=1
# ls

Android 8.0以后

adb shell
# export LIBC_DEBUG_MALLOC_OPTIONS=backtrace
# ls

相关选项功能解释

下面是针对不同的功能,做进一步的解释

保护区相关的设置选项

给对应的option变量或属性,添加如下的值

export LIBC_DEBUG_MALLOC_OPTIONS=leak_track\ backtrace\ front_guard=64\ rear_guard=64

测试代码的例子如下:
在这里插入图片描述
在这里插入图片描述

解释:
front_gurad:指定分配的内存区前面的保护区的大小,在32位系统中,
                   它应该是8字节的倍数,在64位系统中,应该是16字节的倍数。
                   默认是32位字节。最大为16384
                   front_gurad区域默认填充0xaa
rear_gurad:默认被填充0xbb。其余的跟front_guard相同
guard:除了可以分开设置以外,还可以同时设置,使用guard=bytes。

堆栈相关的设置选项

backtrace[=MAX_FRAMES]:设置堆栈的最大深度,默认为16

如下:

export LIBC_DEBUG_MALLOC_OPTIONS=backtrace=10
backtrace_enable_on_signal[=MAX_FRAMES]:如果只打开这个设置,则进程在收到信号时才会
        开始捕获堆栈。信号为45,即kill -45 pid.触发捕获。再次发送同样的信号,则关闭捕获。
        默认情况下关闭捕获。
        如果这个选项和backtrace选项同时使用,则默认打开,在收到信号之后,则关闭。
        MAX_FRAMES可以捕获的最大的帧深度,默认为16,最大为256

backtrace_dump_on_exit:如果backtrace选项打开,那么这个选项,就会在程序退出的时候,
     将dump出堆数据到一个文件中。如果backtrace没有打开,则这个选项不起作用。文件保存在
     /data/local/tmp/backtrace_heap.PID.txt

backtace_dump_prefix:dump文件的前缀,可以用来修改dump出来的文件的位置。默认值为:
    /data/local/tmp/backtrace_heap.
backtrace_min_size=ALLOCATION_SIZE_BYTES:只有大于等于这个值的分配才会被记录。
backtrace_max_size=ALLOCATION_SIZE_BYTES:只有小于等于这个值的分配才会被记录。
backtrace_size=ALLOCATION_SIZE_BYTES:只有大小为这个值的分配才会被记录。
backtrace_full:更全的堆栈信息,这个在Android 10开始,这个标志也会收集java的调用栈.

从Android 14开始,上面这些选项,都有对应的缩写形式。如下

简写全程
btbacktrace
bt_dmp_on_exbacktrace_dump_on_exit
bt_dmp_prebacktrace_dump_prefix
bt_en_on_sigbacktrace_enable_on_signal
bt_fullbacktrace_full
bt_max_szbacktrace_max_size
bt_min_szbacktrace_min_size
bt_szbacktrace_size

填充相关的选项

fill_on_alloc[=MAX_FILLED_BYTES]:每次分配完成之后,就会填充0xeb。后面的数值表示填充的最大的字
     节数为多少。默认是全部填充。注意:calloc不会被填充

fill_on_free[=MAX_FILLED_BYTES]:释放之后,就会填充0xef。后面的数值表示填充的最大字节数。
     默认是全部填充

fill[=MAX_FILLED_BYTES]:表示分配和释放都填充。后面的数字表示填充的最大字节数

expand_alloc[=EXPAND_BYTES]:除了分配指定大小的内存外,再分配点额外的内存。后面的数字就是指定
    额外内存的值。这个值默认为16个字节。最大为16384个字节。

释放相关的选项

free_track[=ALLOCATION_COUNT]:当释放内存的时候,记录下调用栈,并将释放的指针放入一个列表中。
     然后将内存区域填充为0xef。释放的调用栈和分配的调用栈,是分开设置的。默认情况下是16帧。
     最大为256帧。帧的大小可以通过free_track_backtrace_num_frames[=MAX_FRAMES]来设置。
     ALLOCATION_COUNT表示的是列表能保存多少个记录,默认为100,最大为16384。当列表满了之后,
     就会从列表中移除一个,移除的时候,就会检查,内存是否被修改,是否发生“释放后再使用”错误

内存泄漏相关的选项

leak_track:跟踪所有的已经分配的内存。当程序退出时,就会打印未被释放的内存。除此之外,还可以在运行时    
    打印未被释放的内存,见后文的如何查看内存泄漏

分配内存相关的记录

record_allocs[=TOTAL_ENTRIES]:当收到kill -46 pid时,将分配的记录,输出到一个文件中。文件的内容格式,
     详细介绍,见后文。如果有TOTAL_ENTRIES则表明最大的记录数。默认值是:8,000,000,
     最大值为:50,000,000。   一旦分配记录数,超过了TOTAL_ENTRIES,则不在继续记录分配。 
     一旦将这些记录输出到文件,则内存中的分配记录将会被删除,不再保存。
record_allocs_file[=FILE_NAME]:将分配的记录,输出到某个文件中。这个用来指定分配的文件位置和名字。

指针验证相关的选项

verify_pointers:使用一个指针之前,验证一下是否合法。

错误相关的选项

abort_on_error:发送错误消息到log之后,取消错误

log相关的选项

verbose:android 10开始,会将部分的log信息不显示,这样可以让进程启动快一点,如果想要显示这些log,
    则需要将verbose开关打开。

如何DUMP堆中的数据

通过前面的选项介绍,接下来如何将堆中的数据,dump出来进行查看呢。

打开backtrace_dump_on_exit这个选项,则会在程序退出时候将heap中的数据dump出来。一般保存在/data/local/tmp/backtrace_heap.PID.exit.txt中。

注意:如果出现:Unable to create file: /data/local/tmp/backtrace_heap.943.txt这种错误
则需要手动创建文件

除此之外,还可以通过发送信号,将相应的堆dump到文件中,如下:

kill -47  pid

会生成如下的数据
在这里插入图片描述

dump文件解析

## dump的版本号。有v1.0 v1.1 v1.2
Android Native Heap Dump v1.2

## 当前Android设备的fingerprint,这是Android认证必须使用的一个变量
Build fingerprint: 'google/sdk_gphone64_arm64/emu64a:13/TE1A.220922.028/10190541:userdebug/dev-keys'

## 当前分配的总内存
Total memory: 15467419
## 分配记录的个数
Allocation records: 12921
## 栈帧的最大数
Backtrace size: 16



## 第一部分是:分配记录

## 详解如下
z 0  sz   360448  num    1  bt 74f17e16f4 74f17db974 /*省略中间部分指针*/70dfed48
## z后面的数字有两种:0,或者1.  1表示从zygote进程孵化的应用程序分配的。0
##                       则是其他进程分配的,这些进程包括zygote进程本身
## sz 后面的数字:表示此次分配的大小。例子中为360488字节
## num后面的数字:表示此次分配了多少个,这种大小的内存。例子为1个,即只分配了一个大小为
##                       360448字节的大小
## bt 后面的一长串指针:表示的是此次分配的调用栈,可使用地址转换工具,进行查看,
##                       如addr2line。或者llvm-symbolizer


## 如果还打开了backtrace_full开关。则这行下面还有有类似于下面的一行,如下:
bt_info bt_info {"映射名" 176f4 "函数名" 64}
## 映射名:如果对应一个映射,则显示映射的文件名,如果没有,则显示空
## 176f4:相对于映射文件的,一个偏移地址
## 函数名;对应的函数名
## 64:对应于函数的偏移地址



## 第二部分是:映射记录
5fa8f40000-5fa8f42000 r--p 00000000 fe:00 235                            /system/bin/app_process64
## 注意:这部分的详细解释,已经在[android 如何分析应用的内存 (一)](http://t.csdn.cn/zKWGf)

如何查看内存泄漏

如果打开了leak_trace开关,程序在结束运行时,会将没有释放的内存,dump到log系统中。除此之外,还可以在运行时将内存泄漏输出,使用如下的方法:

adb shell dumpsys meminfo --unreachable <PID_OF_APP>

举例如下:

adb shell dumpsys meminfo --unreachable 17609

故意制造一个内存泄漏。如下
在这里插入图片描述

从Android 14开始,增加了一个开关:check_unreachable_on_signal:收到信号之后,将内存泄漏打印到log中。如下

adb shell kill -48 pid

在这里插入图片描述

如何查看内存操作记录

打开record_allocs开关之后,给对应的进程发送46信号,即可dump出内存的操作记录。如下

adb shell kill -46 943

如果出现如下的错误

Cannot create record alloc file /data/local/tmp/record_allocs.txt: Permission denied

则关闭selinux,然后手动创建这个文件。内存操作的记录如下:
在这里插入图片描述
解释如下:


943: malloc 0x7a1f325b10 48
943: malloc 0x79ff317510 8
943: malloc 0x79ff3173b0 8
943: malloc 0x7a1f340cd0 40
943: malloc 0x7a4f31d390 88
943: malloc 0x7a4f31dd30 88
943: malloc 0x7a0f3206e0 24
943: malloc 0x7a3f32d2d0 72
943: malloc 0x7a1f3430d0 40
943: malloc 0x7a2f328a60 64
943: malloc 0x7a0f320320 24
943: malloc 0x7a3f32d030 80
943: malloc 0x7a2f3290a0 64
943: malloc 0x7a0f31fff0 24
##省略部分
943: free 0x7aff337f90
943: calloc 0x7a9f31d6d0 8 32


## 基本格式如下:
##  malloc操作:线程ID,malloc,指针,分配的大小
##  free操作:线程ID,free,指针
##  calloc操作:线程ID,calloc,指针,个数,每个大小
##  realloc操作:线程ID,realloc,新指针,旧指针,大小
##  memalign操作:线程ID,memalign,指针,对齐,大小
##              (对应的函数memalign(alignment, size) ,
##                        aligned_alloc(alignment, size),
##                        posix_memalign(&pointer, alignment, size))
##  memalign操作:线程ID,memalign,指针,4096,大小
##              (对应的函数:valloc(size))
##  memalign操作:线程ID,memalgn,指针,4096,大小四舍五入到4096

注意:不同的Android版本,使用的信号,可能不完全相同。为了查看具体的信号。可以打开verbose开关,然后在log系统中搜索关键字kill即可查看

除了上面介绍的问题以外,“使用错误的指针”,“释放之后再次使用”,“指针越界”,“访问了无效的TAG”等等问题,即可在Android的log中,直接观察到,不再赘述。

特别提醒:当应用中含有第三方so库,而第三方的so库,在malloc debug中导致崩溃。可以将abort_on_error开关打开。这样可以忽略由于第三方so库带来的不必要的崩溃。

至此,Android 7.0之后的malloc debug介绍完毕

Android 7.0之前的malloc debug

注意:Android 4.4 之后,malloc debug的所有功能才开发完成。再此之前,有部分功能是不能用的。好在Android 4.4之前的设备,已经非常稀少了

如何使用

在Android 7.0之前,直接修改libc.debug.malloc属性即可。如下:

adb shell setprop libc.debug.malloc 1

启用成功之后,会在log中看到libc.debug.malloc相关的log。如下
在这里插入图片描述

libc.debug.malloc的值

在上面的libc.debug.malloc的属性中,赋予了一个为1的值,除此之外,还有如下的值可以使用

0: 禁用malloc debug调试功能
1: 在每次分配的时候,会创建一个header区域,这个header区域,包括分配的堆栈。堆栈的帧数最大为
    16。这个选项会导致性能变慢。这些信息,可以通过get_malloc_leak_info函数获得。
    见下一小节的libc回调
5: 启动填充功能,分配内存之后,填充0xeb,用于检测未初始化内存。释放之后填充0xef,用于检测
    “释放之后再次使用”错误。
10:除了启用1中的功能外,还包括如下功能:
   a. 在分配的内存前后设置32字节的保护区,分别填充0xaa和0xbb。用于检查内存越界;
   b. 在释放内存的时候,不马上释放,而是加入一个释放列表中,同时记录释放的堆栈,并填充0xef.
     用于检测“释放之后再次使用”错误,同样堆栈帧也只有16帧。列表长度最长为100个,当超出100时,
     将把最先加入列表的项删除,删除的同时,也会检查是否0xef被修改。
   c. 程序退出时,检查是否有内存未释放,并输出泄漏相关的log

为特定的进程,启用malloc debug功能

可以通过libc.debug.malloc.program属性来指定,如下:

adb shell setprop libc.debug.malloc.program com.example.test_malloc

至此,Android 7.0之前的malloc debug介绍完毕

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/684149.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深入理解Android Jetpack Compose的Box

Box是一个提供了一种快速、简便的方式来对其子元素进行层叠布局的布局组件。 一、什么是Box? 二、如何使用Box? 三、Box中的contentAlignment属性 四、使用Modifier在Box内进行更复杂的布局 一、什么是Box? 在Compose中&#xff0c;Box是一个简单的布局组件&#xff0c…

如何写出高效、准确的会议记录?

在企业或组织中&#xff0c;会议是一种常见的沟通和决策方式。作为参会人员之一&#xff0c;撰写一份高效、准确的会议记录显得尤为重要。会议记录不仅记录了会议的主题、议题和讨论结果&#xff0c;还能帮助参与者回顾会议过程、梳理思路、明确职责&#xff0c;同时也为后续工…

快速入门JavaScript异步编程:从回调到async/await的跨越

文章目录 I. 介绍异步编程的背景和基本概念本文主要讨论JavaScript中的异步编程 II. 回调函数回调函数的定义、作用以及使用场景回调地狱的问题及解决方案 III. PromisePromise的定义、作用以及使用场景Promise的状态及状态转换Promise的链式调用和错误处理 IV. async/awaitasy…

深度学习之目标检测Fast-RCNN模型算法流程详解说明(超详细理论篇)

1.Fast-RCNN论文背景 2. Fast-RCNN算法流程 3.Fast R-CNN 问题和缺点 这篇以对比RCNN来说明&#xff0c;如果你对RCNN网络没太熟悉&#xff0c;可访问这链接&#xff0c;快速了解&#xff0c;点下面链接 深度学习之目标检测R-CNN模型算法流程详解说明&#xff08;超详细理论篇…

合宙Air724UG Cat.1模块硬件设计指南--原理图设计注意事项

在设计原理时注意以下几点&#xff1a; 严格按照模块硬件手册设计原理图 1.调试接口&#xff1a; 调试务必留出usb&#xff08;烧录脚本&#xff0c;升级用&#xff09; ,1.8v&#xff08;开机标志&#xff09;&#xff0c;uboot&#xff08;强制烧录用&#xff09;测试点&…

软件测试面试,大厂上岸究竟有什么秘诀?

最后&#xff0c;总结一下个人认为比较重要的知识点&#xff1a;接口自动化测试 &#xff1a;测试框架&#xff0c;多个有关联的接口的用例编写&#xff0c;用例的组织及存储&#xff0c;接口测试的覆盖率&#xff0c;RESTAssured 的封装等。UI 自动化测试 &#xff1a;iOS 和 …

Web自动化测试之滑动验证码的解决方案

目录 滑动验证破解思路 案例讲解 实现代码 运行效果&#xff1a; 根据传入滑块&#xff0c;和背景的节点&#xff0c;计算滑块的距离 滑动滑块进行验证 总结&#xff1a; 在Web自动化测试的过程中&#xff0c;经常会被登录的验证码给卡住&#xff0c;不知道如何去通过验证…

Prompt不等于编程,“提示词工程师”淘汰程序员也是伪命题

Original 李建忠 李建忠研思 最近ChatGPT及基于大语言模型&#xff08;Large Language Model&#xff0c;以下简写为LLM&#xff09;的Github Copilot等工具出来之后&#xff0c;在软件开发领域也带来了非常大的震撼。著名的观点有Fixie创始人、前Google工程总监Matt Welsh在AC…

解决onblur()失去焦点事件在刚登陆页面(尚未有任何操作)时就触发的问题

文章目录 一、原始错误&#xff1a;1.1 原始代码1.2 访问页面&#xff08;仅访问页面&#xff0c;不进行任何操作&#xff09; 二、解决错误2.1 解决办法2.2 再次访问页面2.2.1 输入错误格式2.2.2 输入正确格式 最近笔者在编写代码时遇到刚访问页面&#xff0c;什么都没有操作&…

JavaWeb学习笔记-1

学习路线 Web开发–介绍&#xff08;画大饼&#xff09; 什么是Web&#xff1f; Web&#xff1a;全球广域网&#xff0c;也成为万维网&#xff0c;能通过浏览器访问的网站 Web网站的工作流程 网站大致是由三个部分组成的 第一部分就是我们能看到的网页程序&#xff0c;也叫做…

React 组件中怎么做事件代理

React 并不会把所有的处理函数直接绑定在真实的dom节点上&#xff0c;而是把所有的事件绑定到结构的最外层&#xff08;合成事件层&#xff09;&#xff0c;使用一个统一的事件监听器&#xff0c;这个事件监听器上维持了一个映射来保存所有组件内部的事件监听和处理函数。 当组…

哈工大计算机网络课程网络层协议详解之:网络地址转换NAT

哈工大计算机网络课程网络层协议详解之&#xff1a;网络地址转换NAT 文章目录 哈工大计算机网络课程网络层协议详解之&#xff1a;网络地址转换NAT网络地址转换&#xff08;NAT&#xff09;NAT实现原理NAT穿透问题NAT穿透问题的解决方案 上一节中&#xff0c;我们在DHCP协议中介…

K 个一组翻转链表

反转链表是比较常出的一种题目&#xff0c;我们有简单难度的一整个链表翻转&#xff1a; private ListNode reverse(ListNode head){ListNode pre null;ListNode cur head;while(cur ! null){ListNode next cur.next;cur.next pre;pre cur;cur next;}return pre;}从第一…

GC说明与介绍,GC的垃圾回收算法有哪些

1、GC是什么 2、GC算法概述 JVM在进行GC时&#xff0c;并非每次都对上面三个内存区域一起回收的&#xff0c;大部分时候回收的都是指新生代。 因此GC按照回收的区域又分了两种类型&#xff0c;一种是普通GC&#xff08;minor GC&#xff09;&#xff0c;一种是全局GC&#xff0…

【算法】行星碰撞机器人碰撞(栈的使用)

文章目录 行星碰撞机器人碰撞参考资料 本文记录了两个使用栈来处理碰撞问题的算法题目。 行星碰撞 https://leetcode.cn/problems/asteroid-collision/ 对于这种题目&#xff0c;各个元素分别会向左或向右移动&#xff0c;可以使用栈模拟碰撞的过程。 由于从左往右进行遍历…

Argis通过Python的Arcpy第三方库进行字段计算、批量将mxd导出为jpg图片、合并数据库

前言 近来公司有开发Arcgis脚本工具的需求&#xff0c;我就去学了一下用Arcpy来操作Arcgis的数据&#xff0c;今天学习了字段计算&#xff0c;将学习成果记录如下。 arcpy帮助文档传送门&#xff1a;https://resources.arcgis.com/zh-cn/help/main/10.2/ 一、字段计算 1、…

Linux学习之内核升级

wget --no-check-certificate https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.1.14.tar.xz下载源代码。 yum install -y gcc gcc-c make ncurses-devel openssl-devel elfutils-libelf-devel安装必要的依赖包。 完成之后&#xff0c;显示如下&#xff1a; …

openEuler操作系统和openGauss数据库

文章目录 1. openEuler操作系统2. openGauss数据库2.1 系统自带库2.1.1 允许所有地址访问端口2.1.2 创建远程登录用户 2.2 安装5.0 版本2.2.1 下载2.2.2 安装2.2.3 测试 1. openEuler操作系统 镜像下载地址 https://www.openeuler.org/zh/download 选一个下载 安装 按提示安…

【kubernetes系列】Kubernetes中的重要概念(三)

在实际的工作中&#xff0c;我们使用Kubernetes 通常不会直接创建 Pod&#xff0c;而是通过 各种 Controller 来管理 Pod 的。Controller 中定义了 Pod 的部署特性&#xff0c;比如有几个副本&#xff0c;在什么样的 Node 上运行等。为了满足不同的业务场景&#xff0c;Kuberne…

VMware Workstation 17 的安装

一、简介 VMware Workstation 17.0是一款功能非常强大的虚拟机&#xff0c;可以帮助用户在Windows系统上同时开启多个系统&#xff0c;不仅能在虚拟机上安装上不同的操作系统&#xff0c;比如Mac、Linux以及Windows10/11等&#xff0c;还能与云技术和容器技术&#xff08;如 D…