今天,我们继续redis源代码test下测试在封装中的其它文件。今天读数memtest档,翻译了,那是,memory test 存储器测试工具。。可是里面的提及了非常多东西,也给我涨了非常多见识,网上关于memtest这样的类似的redis内部边缘的文件解析基本没有,所以自己从头開始学习。机器的内存检測会和机器的CPU位数有关,32位或64位会影响后面的一些宏定义參数。

首先亮出memtest中的API:

/* 内存检測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) /* 开发给整个系统使用的内存检測方法 */

里面基本的方法就几个,每当一个内存检測的開始,都会出现progress bar的图线输出:

/* 内存检測载入開始,输出開始的一些图线显示 */
void memtest_progress_start(char *title, int pass) {int j;/*这里事实上包括2个命令。"\xlb[H","xlb[2j",后面的命令是基本的操作*"\x1b" 是ESC的16进制ASCII码值,这里也可经表示成八进制的\033,*[是一个CSI(Control sequence introducer),转义序列的作用由最后一个字符决定的,*这里J表示删除,默认情况下它删除从当前光标处到行尾的内容,*这里的2为參数,它表示删除全部的显示内容。

也能够使用printf "\x1b[2J"。*/ //现定位home最開始的位置。然后实现请屏幕操作 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/"); //最后一个參数变了,为K,意义也不一样了变成删除当前行操作 printf("\x1b[H\x1b[2K"); /* Cursor home, clear current line. */ printf("%s [%d]\n", title, pass); /* Print title. */ progress_printed = 0; //求出填满progress bar所需点的个数 progress_full = ws.ws_col*(ws.ws_row-3); fflush(stdout); }

我在里面解释了一下清屏操作的。printf输出形式。

内存地址有效性的核心方法;

/* Test that addressing is fine. Every location is populated with its own* address, and finally verified. This test is very fast but may detect* ASAP big issues with the memory subsystem. */
/* 此方法是測试内存地址是否有效。此种检測的速度是很快的。但可能会检測出ASAP的巨大问题 */
/* ASAP网上查了下:(可能为)Automated Statistical Analysis Programme 自己主动统计分析程序 */
void memtest_addressing(unsigned long *l, size_t bytes) {//算出地址的长度unsigned long words = bytes/sizeof(unsigned long);unsigned long j, *p;/* Fill */p = l;for (j = 0; j < words; j++) {//将(unsigned long)p强制类型转换到此时的*p,后面以此来推断,没有转换成功,说明存在内存地址的问题*p = (unsigned long)p;p++;//用A字符填充部分progress barif ((j & 0xffff) == 0) memtest_progress_step(j,words*2,'A');}/* Test */p = l;for (j = 0; j < words; j++) {//比較Address的关键在于if (*p != (unsigned long)p) {printf("\n*** MEMORY ADDRESSING ERROR: %p contains %lu\n",(void*) p, *p);exit(1);}p++;if ((j & 0xffff) == 0) memtest_progress_step(j+words,words*2,'A');}
}

为什么这个方案去检測。本人也是带着比較疑惑的感觉。在内存检測中,内存地址有效性的检查仅仅是当中的一个方法。另一个是内存地址的填充測试,分为随机填充。和给定值的填充。以下给出随机填充的方法实现:

/* Fill words stepping a single page at every write, so we continue to* touch all the pages in the smallest amount of time reducing the* effectiveness of caches, and making it hard for the OS to transfer* pages on the swap. */
/* 在每次写操作的时候,在单页上填满整个字符,这样能够做到最高速的触及全部的页面 */
/* 降低了低效率的缓存使用,可是会让分区在转移页面时会比較困难 */
/* 随机填充内存 */
void memtest_fill_random(unsigned long *l, size_t bytes) {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;assert((bytes & 4095) == 0);for (off = 0; off < step; off++) {l1 = l+off;l2 = l1+words;for (w = 0; w < iwords; w++) {//以下的rand()达到了随机存储的目的
#ifdef MEMTEST_32BIT*l1 = *l2 = ((unsigned long)     (rand()&0xffff)) |(((unsigned long)    (rand()&0xffff)) << 16);
#else*l1 = *l2 = ((unsigned long)     (rand()&0xffff)) |(((unsigned long)    (rand()&0xffff)) << 16) |(((unsigned long)    (rand()&0xffff)) << 32) |(((unsigned long)    (rand()&0xffff)) << 48);
#endifl1 += step;l2 += step;if ((w & 0xffff) == 0)memtest_progress_step(w+iwords*off,words,'R');}}
}

填充内存的优点是訪问页面速度更快,不会出现断断续续的内存片。可是做页面交换的时候。因为没有空间,效率恐怕会比較低下。给定数值的填充与上面的类似,不展开说了。那么,内存測试程序究竟是測哪些东西的呢,也就是说,他这个文件开放给外部的一个最直接的test方法是什么呢?

/* 整个内存检測类操作的測试方法,passes为目标的循环数 */
void memtest_test(size_t megabytes, int passes) {size_t bytes = megabytes*1024*1024;unsigned long *m = malloc(bytes);int pass = 0;if (m == NULL) {fprintf(stderr,"Unable to allocate %zu megabytes: %s",megabytes, strerror(errno));exit(1);}//必须经过passes论循环測试while (pass != passes) {pass++;//地址检測memtest_progress_start("Addressing test",pass);memtest_addressing(m,bytes);memtest_progress_end();//随机填充检測memtest_progress_start("Random fill",pass);memtest_fill_random(m,bytes);memtest_progress_end();//填充后比較四次memtest_compare_times(m,bytes,pass,4);//给定数值填充,这里称为Solid fill固态填充memtest_progress_start("Solid fill",pass);memtest_fill_value(m,bytes,0,(unsigned long)-1,'S');memtest_progress_end();//填充后比較四次memtest_compare_times(m,bytes,pass,4);//也是属于给定数值填充,这里叫Checkerboard fill键盘填充memtest_progress_start("Checkerboard fill",pass);memtest_fill_value(m,bytes,ULONG_ONEZERO,ULONG_ZEROONE,'C');memtest_progress_end();//填充后比較四次memtest_compare_times(m,bytes,pass,4);}free(m);
}

能够看见,分为4中情况,1内存地址測试,2,3,4都为填充測试,分为3种类型的填充Random fill, Solid fill, Checkboard fill 。填充之后再做内存比較,这里的内存比較是在内存内部做前半部分的内存和后半部分的内存比較操作。在memtest文件的最后。提到了一个这个方案:

/* 开发给整个系统使用的内存检測方法 */
void memtest(size_t megabytes, int passes) {if (ioctl(1, TIOCGWINSZ, &ws) == -1) {ws.ws_col = 80;ws.ws_row = 20;}memtest_test(megabytes,passes);printf("\nYour memory passed this test.\n");printf("Please if you are still in doubt use the following two tools:\n");printf("1) memtest86: http://www.memtest86.com/\n");printf("2) memtester: http://pyropus.ca/software/memtester/\n");exit(0);
}

这里提到了memtester和memtest86,上网查了一下,大体例如以下:

* * memtest和memtest86是2款内存检測软件 
 * memtest不但能够彻底的检測出内存的稳定度,还可同一时候測试记忆的储存与检索数据的能力,让你能够确实掌控到眼下你机器上正在使用的内存究竟可不可信赖。 
 * MemTest是一个绿色软件。直接点击执行文件就可以执行 
 * memtest86这是一款小巧而专业的内存測试程序,是在著名的内存測试软件Memtest86基础上开发的。 
 * Memtest86+的安装和使用和其他内存測试软件有些不同,由于他不能在Windows下执行。

* 只是还是有四种方式能够执行此程序,分别为ISO引导盘、Linux下使用的bin文件、
 * USB启动盘使用的EXE文件和软盘引导制作包。

因为Memtest86+測试耗时较长,因此它不仅能够用于内存測试,还能够用于系统稳定性測试。Memtest86+測试完成后,
 * 按“Esc”退出并重新启动系统。

版权声明:本文博主原创文章。博客,未经同意不得转载。

Redis源代码分析(十一年)--- memtest内存测试相关推荐

  1. redis源代码分析 – event library - Dicky - 开源中国社区

    redis源代码分析 – event library - Dicky - 开源中国社区 redis源代码分析 – event library

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

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

  3. Redis源代码分析(十)--- testhelp.h小测试框架和redis-check-aof.c 日志检测

    周期分析struct结构体redis代码.最后,越多越发现很多的代码其实大同小异.于struct有袋1,2不分析文件,关于set集合的一些东西,就放在下次分析好了,在选择下个分析的对象时,我考虑了一下 ...

  4. Redis源代码分析-内存数据结构intset

    这次研究了一下intset.研究的过程中,一度看不下过去,可是还是咬牙挺过来了.看懂了也就是那么回事.静下心来,切莫浮躁 Redis为了追求高效,在存储下做了非常多的优化,像intset就是作者为了节 ...

  5. Redis源代码分析之sds, 动态数组

    Redis是用C语言编写的.C语言处理字符串一向是个难点.很容易出现内存越界问题. 其它高级语言很容易实现的字符串拼接,在C这里却是百般艰难.因为需要实现计算出字符串所占内存的大小.即不能过大(浪费内 ...

  6. 《LINUX3.0内核源代码分析》第一章:内存寻址

    https://blog.csdn.net/ekenlinbing/article/details/7613334 摘要:本章主要介绍了LINUX3.0内存寻址方面的内容,重点对follow_page ...

  7. Android系统匿名共享内存Ashmem(Anonymous Shared Memory)驱动程序源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6664554 在上一文章Android系统匿名共 ...

  8. linux内存测试工具memtest,Linux-内存检测利器Memtest86+v1.70

    [Linux]内存检测利器Memtest86+ v1.70 Memtest86+是一款基于Linux核心的内存检测工具,由x86-secret小组在Chris Brady的Memtest86的基础上增 ...

  9. 测试大白菜软件,大白菜memtest内存清理测试工具的简介

    我们都知道电脑用久了,系统内存会随着程序的运行而增加垃圾文件,从而影响到电脑性能,虽然很多朋友想着要清理电脑的系统内存,但又苦于不知从何下手,今天就给大家介绍下使用u深度memtest内存清理工具来进 ...

最新文章

  1. php -find(),php – beforeFind()添加条件
  2. 最全技术剖析:百度视觉团队获世界最大规模目标检测竞赛冠军
  3. oracle rodo 查看大小,Checkpoint not complete故障
  4. java条件查询excel_[转]EXCEL中的多条件查询(整理)
  5. k8s组件说明:kubelet 和 kube proxy
  6. nvidia的jetson系列的方案_NVIDIAJetson系统在工业网络中的集成
  7. https请求 nginx 不生效_nginx设置https后无法打开网页
  8. 斐讯k2路由虚拟服务器,斐讯K2P不死uboot分享带dhcp server功能
  9. SQL语句写起来太繁琐?你可以试试 MyBatis “动态” SQL
  10. MySQL删除注册表的卸载方式
  11. 机器学习中的各种损失函数(Hinge loss,交叉熵,softmax)
  12. 读书笔记:《浪潮之巅:下》
  13. c语言double型小数点后几位_double类型的数据在输出的时候,C语言编译器对小数部分可以精确到小数点后面的第几位?...
  14. README.txt
  15. python编程图文_深入Python多进程编程基础——图文版
  16. getActivePinia was called with no active Pinia.
  17. 高斯分布-sklearn.mixture.GaussianMixture()
  18. error C3867:非标准语法;请使用“”来创建指向成员的指针
  19. 如何确保有效的软件质量管理流程
  20. NSA组网下2G/3G/4G/5G系统协同策略的研究

热门文章

  1. oracle中数据文件创建,操作oracle中的数据文件
  2. button layui 点击事件_解决layui中的form表单与button的点击事件冲突问题
  3. 2019年下半年软件设计师备考指南
  4. 思科模拟器教程-RIP、OSPF路由协议重发布
  5. 【SVM回归预测】布谷鸟搜索算法优化SVM回归预测【含Matlab源码 1525期】
  6. Java网络编程:TCP实现群聊私聊代码
  7. 一文读懂PFMEA(过程失效模式及后果分析)
  8. 飞行棋小游戏 C#编程记录
  9. Postman进阶篇(一)-pre-request script入门及实现参数使用随机数
  10. (超详细)Navicat的安装和激活,亲测有效