本篇文章给大家谈谈联想笔记本内存条安装教程,以及联想笔记本内存条坏了什么现象的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
文章详情介绍:
深圳联想售后授权点|授权店|联想笔记本电脑升级内存
淘宝网联想笔记本电脑升级内存,笔记本 升级内存
在联想笔记本中安装内存条的步骤如下:
1.先确认一下你的电脑内存的规格,可以让鲁大师测试一下。注意两个主要方面。一个是内存条有多少代,可能2代,3代。二是确认内存条的频率。比如三代内存条1333,1600或者1900等等。
2.确认好自己电脑里内存条的规格后,再去买规格相同的内存条,最好是和自己电脑里内存条同品牌的。
3.打开笔记本电脑的后盖,插入新的内存模块。在这个过程中,你还可以为你的电脑扫尘。
4.最后,安装后盖,重启。
如何安装笔记本内存条?内存是计算机的主要组成部分,是相对于外存储器而言的。平时我们输入一段文字或者玩一个游戏,其实都是在记忆中完成的。通常,我们将大量数据永久保存在外部存储器中,而将一些临时或少量数据和程序放在内部存储器中。那么,内存条安装教程是什么呢?
1.首先你要对你的笔记本电脑做一个全面的评价。从它的定位和实际功能来看,是否能满足你现在的需求,是否值得升级。要知道,即使是最简单的硬件更换也会有潜在的风险,尤其是笔记本电脑等结构复杂的设备。所以,做个评估,如果你觉得没必要升级,就不要冒险升级自己。
2.然后,根据电脑的整体配置,选择合适的内存条。内存芯片到现在已经经历了几代。前几年流行ddr 2,现在DDR 3是主流,DDR 2已经趋于淘汰。所以要搞清楚你的内存条是属于第二代还是第三代。选错了就会出现不兼容,导致升级失败。
3.选择内存模块的容量。容量越大越贵,尤其是现在二代内存比三代内存贵很多。根据自己的实际需求,选择合适容量的内存条。
4.实际安装将从下面开始。首先准备好工具,包括螺丝刀和内存。
5.笔记本背面会有记忆仓的标记。当然,不同型号和品牌的笔记本会有所不同。但都是一样的。小心不要出错。如果不确定,最好查一下说明书或者咨询一下专业人士。
6.打开记忆仓的盖子后,调整插入的金条的记忆金手指的凹槽位置,使其与插槽的固定突起对齐。这其实是工业设计中万无一失的设计。
7.然后以45度左右的角度插入槽内,再轻轻一按,就会发出“啪”的一声,卡入槽内。如果听不到噪音,很可能是安装不正确,需要重新安装。
8.这是内存条卡住时卡扣的样子。注意操作,要小心,不要用力过猛,否则会损坏各种部件。安装完成后,盖上后盖,然后用螺丝刀拧紧螺丝。
9.安装完成后,检查安装是否成功。可以用一些硬件查看类软件查看。
[4001026021]联想笔记本电脑维修中心|联想笔记本电脑清灰换硅脂
联想笔记本电脑使用一段时间后就会出现性能下降,散热差,屏幕暗的情况,导致电脑死机,就需要清灰。笔记本电脑是由主机、显示器、硬盘、 CPU和硅脂组成的。主机包括电源部分、音效部分和接口部分。下面一起来看看联想笔记本电脑清灰换硅脂。
拆下硬盘,使用工具在散热孔上清理灰尘,使用专门的吸尘器对硅脂进行清理,清理完毕之后,就可以把硅脂取出来,在装硅脂之前注意清理电脑内的灰尘。
要注意不要把主板上的风扇给弄坏了,以免主板温度过高。拆下硬盘之后,就可以把主板上的四颗螺丝都拧下来,在主板的背面有一个螺丝刀,拧的时候注意不要太紧,拧好之后把螺丝都拧下来就可以了。为了防止螺丝被弄坏,一定要把螺丝都拧到位之后再拧螺丝,以防拆卸过程中出现意外,让主板产生高温。取出来之后先把主板上的散热器、散热孔里的灰尘清理干净,然后就可以用扳手拧螺丝,直到拧得差不多为止,因为有一些灰尘是很难被拧下来的。然后再把散热器里的散热器固定好,这样就可以用扳手拧下了。
2.装好硅脂后,就可以正常使用了,再次清理就非常容易了,如果 CPU和内存过多清理了也没有效果就可以直接更换 CPU或内存条了。
安装时先用螺丝刀把 CPU和内存条上的螺丝拧掉,然后将散热器装到 CPU上,用扳手将散热器转到 CPU上方后再拧上螺丝。在 CPU上安装好散热器后先将 CPU上的风扇转至高速旋转,因为 CPU上的风扇和散热器之间有一个橡胶垫,所以会对风扇产生一定的摩擦力,但是这一点也不影响风扇的正常工作。当风扇转到高速旋转时再松开油门, CPU上的风扇便会转动起来,这时只要松开油门踏板并慢慢地将风扇转到低速旋转的位置即可。
3.装好后不要直接拔下电源和音效插口,因为在电源上有电源适配器(VGA)这个配件。
插口是和电源连接,插在电源上的插口也是和电源连接的,所以不要直接拔下电源和音效插口。在接口的右侧是个小开关。可以在这个小开关上接一个 USB插口(或者 USB DAC),或者是 HDMI接口。USB转 HDMI接口需要用专用电源适配器(VGA),比如 AOC或RTX3080等,而 VGA要自己买,当然也可以找专业 VGA店去买。
4.在更换硅脂之前一定要先卸下主板上面的主板插口,这是最容易出故障的地方。
当大家更换硅脂之后,会发现,主机的温度会升高。大家应该都知道,硅脂的作用很大,它能够对主板起到保护作用。因此在更换硅脂之前,大家一定要先将主板插口卸下,以免硅脂被污染。否则的话,更换之后,就会出现主板发热,甚至主板上都开始冒黑烟的现象了。
5.在新主板上面加上一层导热垫,这是为了防止新主板与旧主板发生热量交换。
新主板上面的硅脂都已经被拿出来了,大家也可以用刀刮一下,刮下来的硅脂也可以用纸巾擦干净。再用一个透明的硅脂硅片盖在新主板上面,用牙签或针头固定住,这是为了防止主板上的硅脂和散热器发生交换。用新主板上的导热垫给硅脂加温,在旧主板上加硅脂和散热器,这是为了让散热器和硅脂能顺利的接触到新主板上。最后在主板上面加上一层导热垫,就可以把散热器一起装进新主板里面了。注意用螺丝刀把导热垫固定住的地方给撬开了,这样主板上的热量就能顺利的排出去了。
C++常见的三种内存破坏场景和分析
有一定C++开发经验的同学大多数踩过内存破坏的坑,有这么几种现象:
比如某个变量整形,在程序中只可能初始化或者赋值为1或者2, 但是在使用的时候却发现其为0或者其他的情况。对于其他类型,比如字符串等,可能出现了一种出乎意料的值!
程序在堆上申请内存或者释放内存的时候,在内存充足的情况下,居然出现了堆错误。
当出现以上场景的时候,你该思考一下,是不是出现了内存破坏的情况了。而本文主要通过展示和分析常见的三种内存破坏导致覆盖相邻变量的场景,让读者在碰到类似的场景,不至于束手无策。而对于堆上的内存破坏,很常见并且棘手的场景,本人将在后续的文章和大家分享。
1. 内存破坏之强制类型转换大家都知道不匹配的类型强制转换会带来一些bug,比如int和unsigned int互相转换,又或者int和__int64强行转换。是不是每次当读起这类文章起来如雷贯耳,但是当自己去写代码的时候还是容易犯错?这也就是为什么C++容易写出坑的原因,明知可能有错,还难以避免。这往往是因为真实的项目中复杂程度,往往让人容易忽略这些细节。
不少老的工程代码还是采用VC6编译,为了安全问题或者使用C++新特性需要将VC6升级到更新的Visual Studio。接下来要介绍的一个样例程序,就是隐藏于代码中的一个问题,如果从VC6升级到VS2017的时候会带来问题吗?可以先找找看:
#include
Do Task!这个字符串会不会打印出来呢? 可以发现这段程序在VC6中可以打印出来,但是在VS2017中却打印不出来了。那是因为如下原因:
函数原型time_t time( time_t *destTime );,在VC6中time_t默认是32位,而在VS2017中默认是64位。早期程序以为32位中表达最大的时间是2038年,那时候完全够用,但随着计算机本身的发展64位逐渐成为主流time_t在最新的编译器中也默认采用64位,这样时间完全够用以亿年为单位了,那时候计算机发展超出我们想象了。
程序的问题所在m_tRecordTime采用的是int类型,默认为32位,那么其地址作为time_t time( time_t *destTime );函数实参后,在VC6中time_t本身为32位自然也不会出错,但是在VS2017中因为time_t为64位,则time((time_t *)(&m_tRecordTime));后写入了一个64位的值。结合下图,看下这个对象的内存布局,m_bInit的值将会被覆盖,而这里原先的m_bInit的值为1,被覆盖为0,从而导致内存破坏,导致程序执行意想不到的结果。这里只是不输出,那在真实程序中,可能会导致某个逻辑错乱,发生严重的问题。
这个问题修改自然比较简单,将m_tRecordTime定义为time_t类型就可以了。如果有类似的问题发生的时候,比如这个变量的可疑的发生了不该有的变化的时候,你可以查看下这个变量定义的附近是否有内存的操作可能产生溢出,找到问题所在。因为内存上溢的比较多,一般可以查看下定义在当前出现问题的变量的低地址出的变量操作,是否存在可疑的地方。最后,针对这种场景,我们是不是也可以得到一些收获呢,个人总结如下两点:
在定义类型的时候,尽量和原始类型一致,比如这里的time_t有些程序员可能惯性的认为就是32位,那就定义一个时间戳的时候就定义为int了,而我们要做的应该是和原始类型匹配(也就是函数的输入类型),将其定义为time_t,于此类似的还有size_t等,这样可以避免未来在数据集变化或者做平台迁移的时候造成不必要的麻烦。
在有一些复杂的场景的下,也许你不得不做类型转换,而这个时候就格外的需要注意或者了解清楚,转换带来的情况和后果,保持警惕,否则就可能是一个潜在的bug。这和开车一样,当你开车的时候如果看到前方车辆忽然产生一个不合常理的变道行为,首先要做的不是喷那辆车,而是集中注意力,看看是否更前方有障碍物或者事故放生,做出相应的反应。
这种情况应该是最常见了,我们来看一看样例程序:
#include
这种情况下肉眼可以分析的,输出结果为:
在m_str1的空间为5,但是Hi Coder!包含\0是10个字符,在调用strcpy(m_str1, "Hi Coder!");的时候超过了m_str1的空间,于是覆盖了m_str2的内存,从而导致内存破坏。内存溢出这种尤其字符串溢出,程序崩溃可能是小事儿,如果是一个广为流传的软件,那么就很有可能会被黑客所利用。
这种字符串场景如何分析呢,如果程序崩溃了,可以收集Dump先看看被覆盖的地方是什么样的字符串,然后联想看看自己的程序哪里有可能对这个字符串的操作,从而找到原因。别小看这种方法,简单粗暴很有用,曾经就用这种方式分析过Linux驱动模块的内存泄露问题。
那如果还找不到问题呢?如果问题还能重现,那还是有调试手法的,下一节将会进行讲解。
当然最差最差的还是不要放弃代码审查。尤其在这个内存被破坏的附近的逻辑。对于这种场景的建议,比较简单就是使用微软安全函数strcpy_s,注意这里虽然列出了返回值errno_t不过对于微软的实现来说,如果是目标内存空间不够的情况下,在Relase版本下会调用TerminateProcess, 并且要注意的是这个时候抓Dump有时候并不是完整的Dump。
至于微软为什么要这样做,有可能是安全的考虑比崩溃优先级更高,于是在内存溢出不够的时候,直接让程序结束。
errno_t strcpy_s( char *dest, rsize_t dest_size, const char *src);3. 随机性的内存被修改
这一个一听都快崩溃了,C++的坑能不能少一点呢。但是确实是会有各种各样的场景让你落入坑内。上一节的程序我稍作修改:
#include
程序本意是m_str2赋值为Coder, m_str1赋值为Test, 在编程中很多字符串拷贝或者操作中有些是在字符串末尾补\0有的可能不补\0, 而在本例中实际上strcpy_s会自动补0,但是有的程序员防止万一,字符串靠背后,在数组的最后一位设置为’\0’。这种有时候就变成了好心办坏事。
比如这里的m_str1[BUFER_SIZE_STR_2 - 1] = '\0'; ,大家注意到没,这里应该改写为m_str1[BUFER_SIZE_STR_1 - 1] = '\0'; ,也就是说程序员可能拷贝代码或者不小心写错了BUFER_SIZE_STR_2和BUFER_SIZE_STR_1因为两者宏差不多。只要是人写代码,就有可能会犯这种错误。这个程序的输出变为:
这个程序是比较简单,一目了然,但是在大型程序中呢,这个数组的位置跳跃的访问到了其他变量的位置,你首先得判断这个被跳跃式修改的变量,是不是程序本意造成的,因为混合了这么多的猜想,可能会导致分析变的异常复杂。那么有什么好的方法吗?只要程序能偶尔重现这个问题,那就是有方法的。
通过Windbg调试命令ba可以在指定的内存地址做操作的时候进入断点。假设目前已经知道m_str2的第四个字符,总是被某个地方误写,那么我们可以在这个地址处设置一个ba命令: 当写的这个内存地址的时候进入断点。不过这样还是有个问题,那就是程序中有可能有很多次对这块内存的写操作,有时候是正常的写操作,如果一直进入断点,人工分析将会非常累,不现实。
这个时候有个方法,同时也是一个workaround,就是当你还没找到程序出错的根本原因的时候在被误踩的内存前面加上一个足够大的不使用的空间。比如下面的代码, m_str2总是被误写,于是在m_str2的前面加上一个100个字节的不使用的内存m_strUnused(因为一般程序内存溢出是上溢,当然也可以在m_str2的后面同样加上)。
这样我们被踩的内存就很容易落在m_strUnused空间里面了,这个时候我们在其空间里设置写内存操作的断点,就容易捕获到问题所在了。
#include
下面完整的展示一下分析过程:
第一步 用Windbg启动(有的情况下可能是Attach,根据情况而定)到调试进程,设置main的断点
0:000> bp ObjectMemberBufferOverFllow!main
*** WARNING: Unable to verify checksum for ObjectMemberBufferOverFllow.exe
0:000> g
Breakpoint 0 hit
eax=010964c0 ebx=00e66000 ecx=00000000 edx=00000000 esi=75aae0b0 edi=0109b390
eip=003a1700 esp=00defa00 ebp=00defa44 iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
ObjectMemberBufferOverFllow!main:
003a1700 55 push ebp
第二步 使用p命令单步执行代码到testObj.DoSomething();
第三步 找到testObj的地址为00def984
0:000> dv /t /v
00def984 class DemoClass testObj = class DemoClass
第四步 设置断点到testObj相对偏移的位置,这个位置即&m_str1+BUFER_SIZE_STR_2 - 1 = &m_str1+7。并且继续执行代码:
0:000> ba w1 00def984+7
0:000> g
第五步 你会发现程序运行进入断点,这个时候查看对应的函数调用栈即可。这个断点不一定在一个非常精确的位置,但是当你按照函数调用栈去阅读附近的代码,便比较容易找出问题所在了。
0:000> k
# ChildEBP RetAddr
00 00def97c 003a1720 ObjectMemberBufferOverFllow!DemoClass::DoSomething+0x41 [......\strcpybufferoverflow.cpp @ 16]
01 00def9fc 003a1906 ObjectMemberBufferOverFllow!main+0x20 [......\strcpybufferoverflow.cpp @ 30]
02 (Inline) -------- ObjectMemberBufferOverFllow!invoke_main+0x1c [d:\agent\_work\3\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 78]
03 00defa44 75818494 ObjectMemberBufferOverFllow!__scrt_common_main_seh+0xfa [d:\agent\_work\3\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 288]
04 00defa58 770a40e8 KERNEL32!BaseThreadInitThunk+0x24
05 00defaa0 770a40b8 ntdll!__RtlUserThreadStart+0x2f
06 00defab0 00000000 ntdll!_RtlUserThreadStart+0x1b总结
以上对三种内存破坏场景做了分析,在实际应用中将会变的更加复杂。在写代码的时候要注意避开其中的坑,有个叫做墨菲定律,你感觉可能会出问题的地方,那它一定会在某个时刻出现,当你对某个地方有所疑虑的时候一定要多加考虑,否则这个坑可能查找的时间,比写代码的时间要长的许多,更可怕的是可能会带来意想不到的后果。同样的分析问题要保持足够的耐心,相信真相总会出现,这样的底气也是来自于自己平时不断的学习和实践。
内存破坏问题不区分栈上还是堆上,我们在产品中离不开使用堆开间,而且由多个模块核心功能模块组成,而这些模块通常是公用一个进程默认堆的。所以也有人推荐在这些关键模块中,各自创建一个独立的堆,从而降低一个堆内存的使用对另一个堆中内存的影响。虽然不是完全隔离,但是也是一个聊胜于无的操作了。