redis的内存检测会和机器的CPU位数有关,32位或64位会影响后面的一些宏定义参数。首先给出memtest中的API:

void memtest_progress_start(char *title, int pass) /* 内存检测加载开始,输出开始的一些图线显示 */
void memtest_progress_end(void) /* progress bar加载完再次清屏操作 */
void memtest_progress_step(size_t curr, size_t size, char c) /* progress填充自己设置的字符串 */
void memtest_addressing(unsigned long *l, size_t bytes) /* 地址检测方法 */
void memtest_fill_random(unsigned long *l, size_t bytes) /* 随机填充内存 */
void memtest_fill_value(unsigned long *l, size_t bytes, unsigned long v1, unsigned long v2, char sym) /* 像上面的方法,只不过这是特定2种值的填充v1,v2 */
void memtest_compare(unsigned long *l, size_t bytes) /* 内存比较方法 */
void memtest_compare_times(unsigned long *m, size_t bytes, int pass, int times) /* 进行多次内存compare比较操作 */
void memtest_test(size_t megabytes, int passes) /* 整个内存检测类操作的测试方法,passes为目标的循环数 */
void memtest_non_destructive_invert(void *addr, size_t size) /* 将内存地址,进行了按位取反操作,不具有对数据的破坏性 */
void memtest_non_destructive_swap(void *addr, size_t size) /* 将内存地址,2个,2个内部之间做交换,同样不对数据具有破坏性 */
void memtest(size_t megabytes, int passes) /* 开发给整个系统使用的内存检测方法 */

CPU位数的限制:

#if (ULONG_MAX == 4294967295UL)
#define MEMTEST_32BIT
#elif (ULONG_MAX == 18446744073709551615ULL)
#define MEMTEST_64BIT
#else
#error "ULONG_MAX value not supported."
#endif

以其中的接口为例进行说明:

memtest_progress_start:是内存检测开始的接口

内存检测加载开始,输出开始时一些图线显示,一般的test都会有这种显示

void memtest_progress_start(char *title, int pass) {int j;printf("\x1b[H\x1b[2J");    /* Cursor home, clear screen. *//* Fill with dots. */// 填充.for (j = 0; j < ws.ws_col*(ws.ws_row-2); j++) printf(".");printf("Please keep the test running several minutes per GB of memory.\n");printf("Also check http://www.memtest86.com/ and http://pyropus.ca/software/memtester/");printf("\x1b[H\x1b[2K");          /* Cursor home, clear current line.  */// 输出标题printf("%s [%d]\n", title, pass); /* Print title. */progress_printed = 0;// 填满进度条的算法progress_full = ws.ws_col*(ws.ws_row-3);fflush(stdout);
}

memtest_addressing:内测检测的核心算法。

主要看里面的注释部分,其中为什么这样设置,本人也是不理解,请高手留言,在此谢过..........

int memtest_addressing(unsigned long *l, size_t bytes, int interactive) {// 算出地址的lenunsigned long words = bytes/sizeof(unsigned long);unsigned long j, *p;/* Fill */p = l;for (j = 0; j < words; j++) {// 取出p的地址再赋值给p*p = (unsigned long)p;p++;// 用'A'填充progress bar中符合该条件的位置if ((j & 0xffff) == 0 && interactive)memtest_progress_step(j,words*2,'A');}/* Test */p = l;for (j = 0; j < words; j++) {// address比较if (*p != (unsigned long)p) {if (interactive) {printf("\n*** MEMORY ADDRESSING ERROR: %p contains %lu\n",(void*) p, *p);exit(1);}return 1;}p++;if ((j & 0xffff) == 0 && interactive)memtest_progress_step(j+words,words*2,'A');}return 0;
}

还有一种是随机填充memtest_fill_random:在每次写操作的时候,在单页上填满整个字符,这样可以做到最快速的触及所有的页面, 减少了低效率的缓存使用,但是会让分区在转移页面时会比较困难

void memtest_fill_random(unsigned long *l, size_t bytes, int interactive) {// 每次移动的步长unsigned long step = 4096/sizeof(unsigned long);unsigned long words = bytes/sizeof(unsigned long)/2;unsigned long iwords = words/step;  /* words per iteration */unsigned long off, w, *l1, *l2;uint64_t rseed = UINT64_C(0xd13133de9afdb566); /* Just a random seed. */uint64_t rout = 0;assert((bytes & 4095) == 0);for (off = 0; off < step; off++) {l1 = l+off;l2 = l1+words;for (w = 0; w < iwords; w++) {xorshift64star_next();// 填充l1 l2*l1 = *l2 = (unsigned long) rout;l1 += step;l2 += step;// 剩余部分填充Rif ((w & 0xffff) == 0 && interactive)memtest_progress_step(w+iwords*off,words,'R');}}
}

开放给外界的方法:经过passes次的测试才能确定是否通过

int memtest_test(unsigned long *m, size_t bytes, int passes, int interactive) {int pass = 0;int errors = 0;// 运行passes 次while (pass != passes) {pass++;// address testif (interactive) memtest_progress_start("Addressing test",pass);errors += memtest_addressing(m,bytes,interactive);if (interactive) memtest_progress_end();// Random fillif (interactive) memtest_progress_start("Random fill",pass);memtest_fill_random(m,bytes,interactive);if (interactive) memtest_progress_end();errors += memtest_compare_times(m,bytes,pass,4,interactive);// 固定填充if (interactive) memtest_progress_start("Solid fill",pass);memtest_fill_value(m,bytes,0,(unsigned long)-1,'S',interactive);if (interactive) memtest_progress_end();errors += memtest_compare_times(m,bytes,pass,4,interactive);// 使用C字符填充测试if (interactive) memtest_progress_start("Checkerboard fill",pass);memtest_fill_value(m,bytes,ULONG_ONEZERO,ULONG_ZEROONE,'C',interactive);if (interactive) memtest_progress_end();errors += memtest_compare_times(m,bytes,pass,4,interactive);}return errors;
}

总之,内存测试分为4中情况,内存地址测试,其他都为填充测试,分为3种类型的填充Random fill, Solid fill, Checkboard fill 。填充之后再做内存比较,这里的内存比较是在内存内部做前半部分的内存和后半部分的内存比较操作

Redis源码分析之内存检测memtest相关推荐

  1. Redis源码分析(十一)--- memtest内存检测

    今天我们继续redis源码test测试包下的其他文件,今天看完的是memtest文件,翻译器起来,就是memory test 内存检测的意思,这个文件虽然说代码量不是很多,但是里面的提及了很多东西,也 ...

  2. Redis源码分析:基础概念介绍与启动概述

    Redis源码分析 基于Redis-5.0.4版本,进行基础的源码分析,主要就是分析一些平常使用过程中的内容.仅作为相关内容的学习记录,有关Redis源码学习阅读比较广泛的便是<Redis设计与 ...

  3. Redis源码分析(一)redis.c //redis-server.c

    Redis源码分析(一)redis.c //redis-server.c 入口函数 int main() 4450 int main(int argc, char **argv) {4451 init ...

  4. redis源码分析 -- cs结构之服务器

    服务器与客户端是如何交互的 redis客户端向服务器发送命令请求,服务器接收到客户端发送的命令请求之后,读取解析命令,并执行命令,同时将命令执行结果返回给客户端. 客户端与服务器交互的代码流程如下图所 ...

  5. nginx源码分析之内存池与线程池丨nginx的多进程网络实现

    nginx源码分析之内存池与线程池 1. nginx的使用场景 2. nginx源码 内存池,线程池,日志 3. nginx的多进程网络实现 视频讲解如下,点击观看: [Linux后台开发系统]ngi ...

  6. caffe源码分析--SyncedMemory 内存管理机制

    caffe源码分析–SyncedMemory 内存管理机制 ​ SyncedMemory 是caffe中用来管理内存分配和CPU.GPU数据及同步的类,只服务于Blob类.SyncedMemory 对 ...

  7. 10年大厂程序员是如何高效学习使用redis的丨redis源码分析丨redis存储原理

    10年大厂程序员是怎么学习使用redis的 1. redis存储原理分析 2. redis源码学习分享 3. redis跳表和B+树详细对比分析 视频讲解如下,点击观看: 10年大厂程序员是如何高效学 ...

  8. FFMPEG4.1源码分析之 内存管理APIs av_malloc() av_mallocz()

    1  av_malloc() av_malloc() 声明: 所属库:libavutil,该库是ffmpeg的功能库,提供了线程,内存,文件,加密等功能 头文件:libavutil/mem.h 该函数 ...

  9. Redis源码分析(一)--Redis结构解析

    从今天起,本人将会展开对Redis源码的学习,Redis的代码规模比较小,非常适合学习,是一份非常不错的学习资料,数了一下大概100个文件左右的样子,用的是C语言写的.希望最终能把他啃完吧,C语言好久 ...

  10. Redis 源码分析之故障转移

    在 Redis cluster 中故障转移是个很重要的功能,下面就从故障发现到故障转移整个流程做一下详细分析. 故障检测 PFAIL 标记 集群中每个节点都会定期向其他节点发送 PING 消息,以此来 ...

最新文章

  1. Spring 泛型依赖注入
  2. 1071svm函数 r语言_如何利用R语言中的rpart函数建立决策树模型
  3. Matplotlib基础(part1)--基本绘图
  4. java学习(127):finally语句
  5. mac 删除垃圾篓中的文件
  6. android 用户界面教程实例汇总
  7. 诗与远方:无题(七十三)
  8. linux httpd 自动启动,在Linux启动时让Apache也自动启动
  9. Python中的多线程与锁
  10. 设备密码的设置以及遗忘重设置
  11. 用脆弱性评估流程击败黑客
  12. Oracle SQL语句优化【4】之使用SQL优化工具
  13. (2022.9)raspberry 4安装HP 1020 plus打印机,利用树莓派4制作无线打印服务器
  14. Android学习路线指南-------任玉刚
  15. instsrv+srvany 程序以服务方式自启 bat脚本快速配置
  16. 微信小程序换行 br 无效解决方法
  17. Windows安全配置技术(转)
  18. python和scre_python学习日志10
  19. %m.ne用法与讲解
  20. Class文件结构分析

热门文章

  1. 论单片机程序固件保护的重要性和方法
  2. 情侣博客源码php,wordpress如何搭建简单的情侣博客
  3. php manual 下载,PHP - Manual手册 - Download下载
  4. dotween的数值变化_Unity-Dotween
  5. DOTween 使用方法
  6. qq空间把android改成iphone,qq空间改iPhone6 Plus方法 qq空间改手机型号教程
  7. html实现酷狗歌词,酷狗音乐怎么制作歌词?酷狗音乐制作歌词的方法
  8. mysql 数据库数据恢复 库被删了怎么恢复数据库
  9. java数组排序去重_JAVA数组去重排序
  10. Java 数组 快速排序