精华内容
下载资源
问答
  • 内存条的结构及原理
    千次阅读
    2021-07-24 02:58:50

    原标题:解剖U盘存储结构原理

    U盘的结构比较简单,主要是由USB插头、主控芯片、稳压IC(LDO)、晶振、闪存(FLASH)、PCB板、帖片电阻、电容、发光二极管(LED)等组成。

    U盘的基本工作原理也比较简单:USB端口负责连接电脑,是数据输入或输出的通道;主控芯片负责各部件的协调管理和下达各项动作指令,并使计算机将U盘识别为“可移动磁盘”,是U盘的“大脑”;FLASH芯片与电脑中内存条的原理基本相同,是保存数据的实体,其特点是断电后数据不会丢失,能长期保存;PCB底板提供相应处理数据平台,且将各部件连接在一起。

    a603faf00c0030a5c81f5ae652e32ba7.png

    a8a4f92ae95bc0ea4f55eebc4f1916ef.png

    U盘是基于USB接口、以闪存芯片为存储介质的无需驱动器的新一代存储设备。

    U盘使用标准的USB接口,市场上容量一般常用在8G~64G之间,256G在市场上也是能看到的,能够在各种主流操作系统及硬件平台之间作大容量数据存储及交换。其低端产品的市场价格已与软驱接近,而且现在很多主板已支持从USB存储器启动,实用功能更强。U盘有着软驱不可比拟的优势,主要具有体积小、功能齐全、使用安全可靠等特点。但也存在容量还不够大且无法扩充等缺陷。

    USB插头:容易出现和电路板虚焊,造成U盘无法被电脑识别,如果是电源脚虚焊,会使U盘插上电脑无任何反映。有时将U盘摇动一下电脑上又可以识别,就可以判断USB插口接触不良,只要将其补焊即可解决问题。

    稳压IC:又称LDO,其输入端5V,输出3V,有些劣质U盘的稳压IC很小,容易过热而烧毁。还有USB电源接反也会造成稳压IC烧毁。维修时可以用万用表测量其输入电压和输出电压。如无3V输出,可能就是稳压IC坏了。但也有,输出电压偏低,且主控发烫,这时就是主控烧了。

    还有些U盘会在USB+5V和稳压IC之间一个0欧姆的保护电阻,此时稳压IC没有5V输入电压就是它坏了。返回搜狐,查看更多

    责任编辑:

    更多相关内容
  • 图解内存的工作原理及时序介绍

    千次阅读 2021-01-13 15:11:35
    并且,内存原理结构与时序多年不会改变,无论将来内存技术如何进步,相信这篇文章的存在价值都不会打折扣。本文亦希望能通过对DRAM基本原理以及时序的介绍,在内存设置以及XMP的制作上有所帮助


    前言

    内存是PC配件中结构最简单的,但在BIOS中却是最难调的,很多玩家超频都卡在内存上。并且,内存的原理、结构与时序多年不会改变,无论将来内存技术如何进步,相信这篇文章的存在价值都不会打折扣。本文亦希望能通过对DRAM基本原理以及时序的介绍,在内存设置以及XMP的制作上有所帮助。


    第一部分:工作原理

    DRAM基本组成

    • 内存是由DRAM(动态随机存储器)芯片组成的。DRAM的内部结构可以说是PC芯片中最简单的,是由许多重复的“单元”——cell组成,每一个cell由一个电容和一个晶体管(一般是N沟道MOSFET)构成,电容可储存1bit数据量,充放电后电荷的多少(电势高低)分别对应二进制数据0和1。
    • 由于电容会有漏电现象,因此过一段时间之后电荷会丢失,导致电势不足而丢失数据,因此必须经常进行充电保持电势,这个充电的动作叫做刷新,因此动态存储器具有刷新特性,这个刷新的操作一直要持续到数据改变或者断电。而MOSFET则是控制电容充放电的开关。DRAM由于结构简单,可以做到面积很小,存储容量很大。
      在这里插入图片描述

    内存地址

    • 内存中的cell按矩阵形排列,每一行和每一列都会有一个对应的行地址线路(正规叫法叫做word line)和列地址线路(正规叫法是bit line),每个具体的cell就挂接在这样的行地址线路和列地址线路上,对应一个唯一的行号和列号,把行号和列号组合在一起,就是内存的地址。
      在这里插入图片描述
    • 上图是Thaiphoon Burner的一个SPD dump,每个地址是一个字节。不过我们可以把这些数据假设成只有一个bit,当成是一个简单的内存地址表,左边竖着的是行地址,上方横着的是列地址。例如我们要找第七行、倒数第二列(地址为7E)的数据,它就只有一个对应的值:FD。当然了,在内存的cell中,它只能是0或者1。

    寻址

    • 数据要写入内存的一个cell,或者从内存中的一个cell读取数据,首先要完成对这个cell的寻址。寻址的过程,首先是将需要操作的cell的对应行地址信号和列地址信号输入行/列地址缓冲器,然后先通过行解码器(Row Decoder)选择特定的行地址线路,以激活特定的行地址。
    • 每一条行地址线路会与多条列地址线路和cell相连接,为了侦测列地址线路上微弱的激活信号,还需要一个额外的感应放大器(Sense Amplifier)放大这个信号。
    • 当行激活之后,列地址缓冲器中的列地址信号通过列解码器(Column Decoder)确定列地址,并被对应的感应放大器通过连接IO线路,这样cell就被激活,并可供读写操作,寻址完成。从行地址激活,到找到列地址这段时间,就是tRCD。
      在这里插入图片描述

    内存cell的基本操作

    • 内存中的cell可以分为3个基本操作,数据的储存、写入与读取。为了便于理解,我不打算直接从电路控制上对cell操作进行说明,而是希望通过模型类比来达到说明问题的目的,如有不严谨之处,高手勿怪。要对内存cell进行读写操作,首先要完成上述寻址过程,并且电容的充电状态信号要被感应放大器感应到,并且放大,然后MOSFET打开,电容放电,产生电势变化,把电荷输送到IO线路,导致线路的电势也变化。当然,这只是个简单的描述,以下我们先来了解硅晶体中“电容”的结构和MOSFET的控制原理。

    硅晶体中的“电容”

    • 这里之所以“电容”两个字被打上引号,是因为硅晶体中并没有真正意义上的电容。硅晶体中的电容是由两个对置的触发器组成的等效电容。例如两个非门(Nor Gate)用如下图的方式对接。它可以通过周期性施加特定的输入信号,以把电荷保留在电路中,充当电容的作用。如下图,两个非门的输入端R和S互相交替做0和1输入,就可以把电荷储存在电路中。整个动态过程就是这样:
      在这里插入图片描述
    • 而R和S的波形就是如下图所示,刚好互为反相,差半个周期:
      在这里插入图片描述
    • 要让电容放电,我们只需要把R和S同时输入1或者0即可。因此这种电容的逻辑关系很简单:在同一时刻R和S输入状态不同(即存在电势差)时,电容为充电状态;在同一时刻R和S输入状态相同(即电势差为0)时,电容为放电状态。
      在这里插入图片描述

    MOSFET的控制原理——水库模型

    • 要说明这个MOSFET的控制原理,我们借助一个水库的模型来说明。MOSFET有三个极,分别是源极(Source)、漏极(Drain)和栅极(Gate)。下图左边就是一个MOSFET的电路图,右边是我们画出的一个水库模型。
      在这里插入图片描述
    • 图中S为源极,D为漏极,G为栅极。S极连接着电容,D级连接列地址线路,并接到数据IO,G则是控制电荷流出的阀门,连接行地址线路。电容在充电后电势会改变,这样S极的电势就会跟着改变,与D极形成电势差,而G极的电势,就决定了S极有多少电荷可以流入D极。
    • 由于电子是带负电荷,因此电子越多电势就越低。为了不至于混淆概念,我们把水池顶部电势定为0V,水池底部电势定为5V(仅举例说明,DRAM中的电容实际电压未必是5V)。当电子数量越多时,电势越低,接近0V,电子数量越少时,电势越高,接近5V。
      在这里插入图片描述
    • 用水库模型说明,就是左边的水池水量升高(电容充电后),当阀门关闭时,左边的水是不会往右边流的。然后阀门打开(降低,电势升高),左边的水就可以往右边流,阀门的高度就决定了有多少水能流去右边的水道(但是在数字电路中,MOSFET只有开和关两种状态,因此下文提到的打开MOSFET就是全开);
    • 同样道理如果右边水多,阀门打开之后也可以向左边流。因此在水库模型中,电容就充当了左边的水池,而MOSFET的栅极就充当了阀门,列地址线路和IO则充当了右边的水道。

    储存数据

    • MOSFET栅极电势为0V时,电容的电荷不会流出,因此数据就可以保存我们可以用2.5V为参考分界线,电容电势低于2.5V时,表示数据0,电势高于2.5V时,表示数据1。例如上一楼水库模型的左图,电容中储存的电子数高于一半的高度,电势低于2.5V,因此可以表示数据0。
    • 但以上只是理论情况,实际上电容会自然漏电,电子数量会逐渐减少,电势就会逐渐升高,当电势升高到2.5V以上时,数据就会出错,因此每隔一段时间必须打开MOSFET往电容中充电,以保持电势,这就是刷新。因此,数据的储存主要就是对电容中电势的保持操作。

    写入数据

    • 数据写入的操作分为写入0和写入1两种情况。写入前,电容原有的情况可能是高电势与低电势的状态,我们不用管它。写入0和写入1对cell的操作不尽相同,我们分别来看。
    • 先来看写入0的操作。写入开始时,IO线路上电势为0(水道处于水位最高点),MOSFET栅极电势升高到5V(水库阀门降到最低),阀门打开,电容中的电势就跟着降低(水位升高),直到接近0V(水池被灌满),写入0完成,栅极电势降回0V,阀门关闭。
      在这里插入图片描述
    • 再看写入1的操作。写入开始时,IO线路上的电势为5V(水道水位为最低点),MOSFET栅极电势升高到5V(水库阀门降到最低),阀门打开,电容中的电势跟着升高(水流出并降低水位)到接近5V,写入1完成,栅极电势回到0V,阀门关闭。
      在这里插入图片描述

    读取数据

    • 读取的时候,对漏极的电压操作跟写入有些不同。因为水道中的水比水池中的多,或者说水道的容量比水池要大得多。如果水道(漏极)的水为满或者空,在阀门打开的时候很容易出现水道的水倒灌进水池的现象,或是水池的水全部流去水道,这样就有可能导致电容中的电势状态改变,电容对应储存的0或者1也会改变。所以读取数据的时候,IO线路的电压应为1/2的满电势,即2.5V。
    • 读取也同样分读取0和1两种情况。在读取之前,电容中的电势应该是大于或者小于2.5V的,分别代表存储了1和0。由于刷新机制的存在,应该不会允许出现等于2.5V的情况。
    • 首先看读取0操作。电容中为低电势(假设为0V,水池为高水位),IO线路上电势升高至2.5V(这时水道水位比水池低),MOSFET栅极电势升高到5V(水库阀门降到最低),阀门打开,电容中电势升高(水位降低),但由于水道容量较大,因此水位不会升高太多,但是总归也会有个电势的变低,最终电容与IO线路上的电势都变成0-2.5V的一个中间值,并且接近2.5V(假设为2.3V)。这时候感应放大器检测到IO线路上电势低于2.5V,因此识别出0读出。
      在这里插入图片描述
    • 再看读取1操作。电容中为高电势(假设为5V,水池空),IO线路上电势升高至2.5V(这时候水道水位比水池高),MOSFET栅极电势升高到5V(水库阀门降到最低),阀门打开,电容中电势降低(水位升高),但由于水道容量较大,水位不会降低太多,不过多少也会降低一点(电势会升高),假设升高到2.7V。这时候感应放大器检测到IO线路的电势高于2.5V,识别出1读出。
      在这里插入图片描述
    • 以上讲述的只是从cell到内存IO线路的读写操作,至于CPU-IMC-内存的读写操作,不在本文讨论范围。

    二、时序介绍

    时序及相关概念

    • 以下我把时序分为两部分,只是为了下文介绍起来作为归类,非官方分类方法。
    • 第一时序:CL-tRCD-tRP-tRAS-CR,就是我们常说的5个主要时序。
    • 第二时序:(包含所有XMP时序)
    • 在讲时序之前,我想先让大家明白一些概念。内存时钟信号是方波,DDR内存在时钟信号上升和下降时各进行一次数据传输,所以会有等效两倍传输率的关系。
    • 例如DDR3-1333的实际工作频率是666.7MHz,每秒传输数据666.7*2=1333百万次,即1333MT/s,也就是我们说的等效频率1333MHz,再由每条内存位宽是64bit,那么它的带宽就是:
    1333MT/s*64bit/8(8bit是一字节)=10667MB/s。
    
    • 所谓时序,就是内存的时钟周期数值,脉冲信号经过上升再下降,到下一次上升之前叫做一个时钟周期,随着内存频率提升,这个周期会变短。例如CL9的意思就是CL这个操作的时间是9个时钟周期。
    • 另外还要搞清楚一些基本术语:

    Cell:颗粒中的一个数据存储单元叫做一个Cell,由一个电容和一个N沟道MOSFET组成。
    Bank:8bit的内存颗粒,一个颗粒叫做一个bank,4bit的颗粒,正反两个颗粒合起来叫做一个bank。一根内存是64bit,如果是单面就是8个8bit颗粒,如果是双面,那就是16个4bit的颗粒分别在两面,不算ECC颗粒。
    Rank:内存PCB的一面所有颗粒叫做一个rank,目前在Unbuffered台式机内存上,通常一面是8个颗粒,所以单面内存就是1个rank,8个bank,双面内存就是2个rank,8个bank。Bank与rank的定义是SPD信息的一部分,在AIDA64中SPD一栏可以看到。
    DIMM:指一条可传输64bit数据的内存PCB,也就是内存颗粒的载体,算上ECC芯片,一条DIMM PCB最多可以容纳18个芯片。

    第一时序

    • CAS Latency(CL):CAS即Column Address Strobe,列地址信号,它定义了在读取命令发出后到数据读出到IO接口的间隔时间。由于CAS在几乎所有的内存读取操作中都会生效(除非是读取到同一行地址中连续的数据,4bit颗粒直接读取间隔3个地址,8bit颗粒直接读取间隔7个地址,这时候CAS不生效),因此它是对内存读取性能影响最强的。如下图,蓝色的Read表示读取命令,绿色的方块表示数据读出IO,中间间隔的时间就是CL。
      在这里插入图片描述
    • 已知CL时钟周期值CAS,我们可以使用以下公式来计算实际延迟时间tCAS:
    tCAS(ns)=(CAS*2000)/内存等效频率
    
    • 例如,DDR3-1333 CL9内存实际CAS延迟时间=(9*2000)/1333=13.50 ns
      或者反过来算,假如已知你的内存可以在7.5ns延迟下稳定工作,并且你想要DDR3-2000的频率,那么你可以把CL值设为8T(实际上8ns,大于7.5ns即可),如果你想要DDR3-1600的频率,那么你的CL值可以设到6T(实际7.5ns)。
      这个公式对于所有用时钟周期表示延迟的内存时序都可以用。
    • 说到这个公式,我想顺便说说大家对频率和时序的纠结问题。首先来回顾一下DDR一代到三代的一些典型的JEDEC规范,并按照上边那个公式算一下它的CL延迟时间:
    DDR-400 3-3-3-8:(3*2000)/400=15 ns
    DDR2-800 6-6-6-18:(6*2000)/800=15 ns
    DDR3-1333 9-9-9-24:刚才算了是13.5 ns
    
    • 再来看看每一代的超频内存的最佳表现(平民级,非世界纪录):
    DDR1 Winbond BH-5 DDR-500 CL1.5:(1.5*2000)/500=6 ns
    DDR2 Micron D9GMH DDR2-1400 CL4:(4*2000)/1400=5.71 ns
    DDR3 PSC A3G-A DDR3-2133 CL6:(6*2000)/2133=5.63 ns
    
    • 发现什么?不管是哪一代内存,随着频率提升,CL周期也同步提升,但是最后算出来的CL延迟时间却差不多。那么到了DDR4,JEDEC规范频率去到DDR4-4266,如果按照差不多的延迟,那么按照13ns多一些来算,那么CL值将达到28T!如果按照我们的极限超频延迟来算,DDR4-4266下的延迟也将达到12T。所以到了下一代DDR4,两位数的时钟周期将不可避免。
    • 所以,我想说的是,不要再去想什么DDR3的频率,DDR2的时序,在频宽严重过剩,IMC成为瓶颈的今天,它对性能没太多的提升。
    • DRAM RAS to CAS Delay(tRCD):RAS的含义与CAS类似,就是行(Row)地址信号。它定义的是在内存的一个rank(内存的一面)之中,行地址激活(Active)命令发出之后,内存对行地址的操作所需要的时间。
    • 每一个内存cell就是一个可存储数据的地址,每个地址都有对应的行号和列号,每一行包含1024个列地址,当某一行地址被激活后,多个CAS请求会被发送以进行读写操作。简单的说,已知行地址位置,在这一行中找到相应的列地址,就可以完成寻址,进行读写操作,从已知行地址到找到列地址过去的时间就是tRCD。当内存中某一行地址被激活时,我们称它为“open page”。
    • 在同一时刻,同一个rank可以打开8个行地址(8个bank,也就是8个颗粒各一个)。下图显示一个行地址激活命令发出,到寻找列地址并发出读取指令,中间间隔的时间就是tRCD。tRCD值由于是最关键的寻址时间,它对内存最大频率影响最大,一般想要上高频,在加电压和放宽CL值不奏效的时候,我们都要放宽这个延迟。
      在这里插入图片描述
    • DRAM RAS Precharge Time(tRP):RAS预充电时间。它定义的是前一个行地址操作完成并在行地址关闭(page close)命令发出之后,准备对同一个bank中下一个行地址进行操作,tRP就是下一个行地址激活信号发出前对其进行的预充电时间。由于在行地址关闭命令发出之前,一个rank中的多个行地址可能正在被读写,tRP对内存性能影响不如CL和tRCD。
    • 虽然tRP的影响会随着多个行地址激活与关闭信号频繁操作一个bank而加大,但是它的影响会被bank interleaving(bank交叉操作)和command scheduling(命令调配)所削弱。交叉读写会交替使用不同的bank进行读写,减少对一个bank的操作频率;
    • 命令调配则是由CPU多线程访问不同的内存地址,同样是减少对一个bank的频繁操作次数。例如SNB CPU的内存控制器可以对读写操作命令进行有效地重新分配,以使得行地址激活命中率最大化(如果重复激活一个已经处于激活状态的行地址,那就是RAS激活命令未命中),所以tRP在SNB平台对性能的影响不大,并且放宽它有可能可以帮助提升稳定性。下图显示的是一个即将被激活的行地址开始预充电,到它被激活间隔的时间,就是tRP。
      在这里插入图片描述
    • DRAM RAS Active Time(tRAS):行地址激活的时间。它其实就是从一个行地址预充电之后,从激活到寻址再到读取完成所经过的整个时间,也就是tRCD+tCL的意思。这个操作并不会频繁发生,只有在空闲的内存新建数据的时候才会使用它。太紧的tRAS值,有可能会导致数据丢失或不完整,太宽的值则会影响内存性能,尤其是在内存使用量增加的时候。所以一般为了稳定性,我们设置tRAS≥tRTP+tRCD+CL即可(tRTP不是tRP,将在第二时序中介绍),尤其是PCB不好或者跑高频的时候,多几个周期比较稳妥。
    • DRAM Command Mode(Command Rate,CR):首命令延迟,也就是我们平时说的1T/2T模式。是指从选定bank之后到可以发出行地址激活命令所经过的时间。
    • CR可能对性能的影响有比较大的变数:如果CPU所需要的数据都在内存的一个行地址上,就不需要进行重复多次的bank选择,CR的影响就很小;但是如果一个rank中同时多个bank要激活行地址,或者不同的rank中不同bank需要同时激活的时候,CR对性能的影响就会提升。但是随着内存频率的提升,CR=1T/2T的时间差越短,它的影响就会越来越小,这就是我们看到DDR1的时候1T/2T对性能影响挺大,但是到了DDR3影响就很小的其中一个原因。但是为了性能最大化,我们尽量把CR设为1T,但是如果bank数很多的时候,例如插满四条内存,就有32个bank,bank选择随机性增大,1T的首命令时间可能会不稳定。
    • 所以,内存的基本读取操作的时序角度流程就是把上面那三张图合起来:预充电-激活行地址并寻找列地址-发送读取命令-读出数据,这四步操作中间的三个延迟就分别是tRP、tRCD和CL。和我们常说的时序顺序刚好是反过来的。

    第二时序——XMP

    • DRAM CAS Write Latency(tWCL):列地址写入延迟,也就是DRAM的最小写入操作时间,与CL刚好是读写对应关系,一般跟CL值设为同一个值就是可以稳定的。由于内存读取之前必须先写入,所以这个值可以说与CL一样重要。但是在BIOS里一般没得设置,可能是与CL绑定了。
    • DRAM Row Cycle Time(tRC):行周期时间。定义了同一bank两次行激活命令所间隔的最小时间,或者说是一个bank中完成一次行操作周期(Row Cycle)的时间,即tRP+tRAS(预充电加上激活的整个过程),tRC设得太紧可能会直接点开不了机,一般只要能进系统再多加一两个周期都是可以稳定的。下图显示的就是tRC的时间。
      在这里插入图片描述
    • DRAM Row Refresh Cycle Time(tRFC):行地址刷新周期,定义了一个bank中行地址刷新所需要的时间。重提一下刷新的含义,由于cell中电容的电荷在MOSFET关闭之后一段时间就会失去,为了维持数据,每隔很短一段时间就需要重新充电。
    • 这里多提一句,Intel平台和AMD平台对tRFC的含义不一样,AMD平台的tRFC是DRAM刷新延迟时间,单位是ns,通常有90/110/160/300几个值可以调整,也就是说它的tRFC时钟周期会随着频率的提升而提升;而Intel平台的单位则直接是时钟周期,相反地延迟时间会随着频率的提升而降低。容量大的bank行地址和cell会更多,刷新时间也更长,因此tRFC也要更高。另外,tRFC如果太快会导致数据出错,太慢则影响性能,但可以增加稳定性。
    • DRAM Refresh Interval(tREFI):内存刷新时间间隔,也就是内存的刷新命令生效前要经过的时间。刷新的时间间隔一般取决于内存颗粒的容量(density),容量越大,就越需要频繁刷新,tREFI值就要越低。另外tREFI的时间也会受到内存工作温度与内存电压(Vdimm)影响,因为温度越高电容漏电越快。
    • 一般在AMD主板的BIOS里,这个值只有3.9us和7.8us可选,而在SNB平台,则是按时钟周期算,例如DDR3-1333下默认值为5199T,换算过来就是2000/1333x5199=7800ns,也就是7.8us。一般DRAM颗粒的spec中都是规定工作温度大于85度时采用3.9us。
    • DRAM RAS to RAS Delay(tRRD):行地址间延迟,定义的是同一rank不同bank间两个连续激活命令的最短延迟,在DDR3时代一般最小是4T。它的作用和CR有点像,不过比CR更多的时候对性能有较大的影响,所以这个时序可尽量缩小。
    • DRAM Write Recovery Time(tWR):内存写入恢复时间,它定义了内存从写入命令发出(从开始写入算起)到下一次预充电间隔的时间,也就是tRP的前一个操作。如果这个时间设得太短,可能会导致前一次写入未完成就开始下一次预充电,进行寻址,那么前一次写入的数据就会不完整,造成丢数据的情况。这个周期也是第二时序中比较长的,DDR3-2000一般需要10-14个周期,甚至更高。
    • DRAM Read to Precharge Time(tRTP):与tWR类似,定义了同一rank上内存从读取命令发出到tRP之前的间隔时间,但是它在读取完成并且行地址关闭之后才会生效。单颗128MB的内存颗粒可以在DDR3-2000下运行在4到6个时钟周期,如果bank容量增大时,这个时序有可能要放宽。
    • DRAM Four Active Window(tFAW):它定义了同一rank中允许同时发送大于四个行激活命令的间隔时间,因此最小值应该不小于tRRD的四倍。在DDR3上,tRRD的最小值是4T,因此tFAW的最小值就是16T。这个tFAW由于是在一个rank中大于四个bank同时激活之后才生效,因此在内存不是很繁忙的时候,它对性能的影响并不是很大。但是对一些频繁读写内存的操作(例如SuperPI 32M),tFAW对性能的影响可能会加大。
    • 由于现在内存用满的几率非常非常小,两根双面的内存更是有4个rank,配合上interleaving,一个rank中同时激活大于四个bank的几率应该不大,所以通常我们把它设为tRRD的四倍应该就不会出问题。
    • DRAM Write to Read Delay(tWTR):内存写-读延迟,它定义的是内存写入命令发出后到下一个读取命令之间的时间间隔,最小为4T,与tRTP类似,提升内存的频率或者容量提升时,这个值需要提高。

    总结

    看完以上内容,我们已经对时序有了个大致的了解,现在应该可以知道一些时序设置时要注意什么了。比如tFAW要设为tRRD的四倍,tRAS不能设太低等等。还是那句话,内存是辅助CPU超频的,时序设置只是为了放开内存更多的超频空间,时序本身对性能的影响很小,并且随着频率的提升,或者bank数的增加,这种影响可能会进一步减小。具体不同的内存颗粒也会有不同的设置情况,还请大家多关注本站的颗粒汇总以及最新内存颗粒测试报告!。

    展开全文
  • JVM内存结构详解

    万次阅读 多人点赞 2020-04-28 12:09:06
    文章目录一、你了解JVM内存模型吗在这之前需要知道JVM内存模型图——JDK1.81.1、程序计数器1.2、Java虚拟机栈(Stack)1.1.1、java.lang.StackOverflowError问题1.3、本地方法栈1.4、元空间(MetaSpace)1.4.1、...

    一、你了解JVM内存结构吗

    在这之前需要知道

    内存寻址过程
    在这里插入图片描述

    地址空间划分

    • 内核空间是用于连接硬件,调度程序联网等服务
    • 用户空间,才是java运行的系统空间

    我们知道JVM是内存中的虚拟机,主要使用内存进行存储,所有类、类型、方法,都是在内存中,这决定着我们的程序运行是否健壮、高效。

    JVM内存结构图——JDK1.8

    在这里插入图片描述

    • 线程私有:程序计数器、虚拟机栈、本地方法栈
    • 线程共享:MetaSpace、Java堆
      下面我们会对图中五个部分进行详细说明

    1.1、程序计数器

    • 当前线程所执行的字节码行号指示器(逻辑)
    • 通过改变计数器的值来选取下一条需要执行的字节码指令
    • JVM的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器只会执行一条线程中的指令,为了线程切换后能够恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程计数器不会互相影响。所以,程序计数器和线程是一对一的关系即(线程私有
    • 对Java方法计数,如果是Native方法则计数器值为Undefined,Native方法是由非Java代码实现的外部接口
    • 程序计数器是为了防止内存泄漏
      在后边的举例中我们可以看到程序计数器的作用。

    1.2、虚拟机栈(JVM Stack)

    • Java方法执行的内存模型
    • 生命周期和线程是相同的,每个线程都会有一个虚拟机栈,栈的大小在编译期就已经确定了
    • 栈的变量随着变量作用域的结束而释放,不需要jvm垃圾回收机制回收。
    • 包含多个栈帧
      • 栈帧包含
        • 局部变量表
          • 包含方法执行过程中的所有变量(所有类型)
        • 操作数栈
          • 入栈、出栈、复制、交换、产生消费变量
        • 动态连接
        • 返回地址
          在这里插入图片描述

    在Java虚拟机栈中,一个栈帧对应一个方法,,方法执行时会在虚拟机栈中创建一个栈帧,而且当前虚拟机栈只能有一个活跃的栈帧,并且处于栈顶,当前方法结束后,可能会将返回值返回给调用它的方法,而自己将会被弹出栈(即销毁),下一个栈顶将会被执行。

    举例说明:

    ByteCodeSample.java

    package com.mtli.jvm.model;
    
    /**
     * @Author: Mt.Li
     * @Create: 2020-04-26 17:47
     */
    public class ByteCodeSample {
        public static int add(int a , int b) {
            int c= 0;
            c = a + b;
            return c;
        }
    }
    
    

    对其进行编译生成.class文件

    javac com/mtli/jvm/model/ByteCodeSample.java
    

    然后用javap -verbose 进行反编译

    javap -verbose com/mtli/jvm/model/ByteCodeSample.class
    

    生成如下:

    Classfile /E:/JavaTest/javabasic/java_basic/src/com/mtli/jvm/model/
    ByteCodeSample.class
      Last modified 2020-4-26; size 289 bytes
      MD5 checksum 2421660bb241239f1a67171bb771521f
      Compiled from "ByteCodeSample.java"
    public class com.mtli.jvm.model.ByteCodeSample
      minor version: 0
      major version: 52
      flags: ACC_PUBLIC, ACC_SUPER
    // 描述类信息
    Constant pool:
       #1 = Methodref          #3.#12         // java/lang/Object."<ini
    t>":()V
       #2 = Class              #13            // com/mtli/jvm/model/Byt
    eCodeSample
       #3 = Class              #14            // java/lang/Object
       #4 = Utf8               <init>
       #5 = Utf8               ()V
       #6 = Utf8               Code
       #7 = Utf8               LineNumberTable
       #8 = Utf8               add
       #9 = Utf8               (II)I
      #10 = Utf8               SourceFile
      #11 = Utf8               ByteCodeSample.java
      #12 = NameAndType        #4:#5          // "<init>":()V
      #13 = Utf8               com/mtli/jvm/model/ByteCodeSample
      #14 = Utf8               java/lang/Object
     // 以上是常量池(线程共享)
    {
      public com.mtli.jvm.model.ByteCodeSample();
        descriptor: ()V
        flags: ACC_PUBLIC
        Code:
          stack=1, locals=1, args_size=1
             0: aload_0
             1: invokespecial #1                  // Method java/lang/O
    bject."<init>":()V
             4: return
          LineNumberTable:
            line 8: 0
    // 以上是初始化过程
      public static int add(int, int);
        descriptor: (II)I  // 接收两个int类型变量
        flags: ACC_PUBLIC, ACC_STATIC // 描述方法权限和类型
        Code:
          stack=2, locals=3, args_size=2 // 操作数栈深度 、 容量  、参数数量
             0: iconst_0
             1: istore_2
             2: iload_0
             3: iload_1
             4: iadd
             5: istore_2
             6: iload_2
             7: ireturn
          LineNumberTable:
            line 10: 0 // 这里的第0行对应我们代码中的第10行
            line 12: 2
            line 13: 6
    }
    SourceFile: "ByteCodeSample.java"
    
    

    执行add(1,2)

    以下是程序在JVM虚拟机栈中的执行过程

    在这里插入图片描述

    • 最开始,我们int c = 0,所以操作数栈顶初始值为0,局部变量表存储变量值。
    • istore_2 就是出栈的意思,将0放入变量表2的位置
    • iload_0 就是入栈,将1复制并压入操作数栈
    • 然后将位置在1的值“2”压入栈
    • 在栈中执行add方法,得到“3”
    • 将栈顶“3”取出到变量表的2位置
    • 再次将“3”压入栈,准备return
    • 方法返回值

    执行完之后,当前线程虚拟机栈的栈帧会弹出,对应的其他方法与当前栈帧的连接释放、引用释放,它的下一个栈帧成为栈顶。

    1.1.1、java.lang.StackOverflowError问题

    我们知道,一个栈帧对应一个方法,存放栈帧的线程虚拟栈是有深度限制的,我们调用递归方法,每递归一次,就会创建一个新的栈帧压入虚拟栈,当超出限度后,就会报此错误。

    举例说明:

    package com.mtli.jvm.model;
    
    /**
     * @Description:斐波那契
     * F(0)=0,F(1)=1,当n>=2的时候,F(n) = F(n-1) + F(n-2),
     * F(2) = F(1) + F(0) = 1,F(3) = F(2) + F(1) = 1+1 = 2
     * 0, 1, 1, 2, 3, 5, 8, 13, 21, 34...
     * @Author: Mt.Li
     * @Create: 2020-04-26 18:33
     */
    public class Fibonacci {
        public static int fibonacci(int n) {
            if(n>=0){
                if(n == 0) {return 0;}
                if(n == 1) {return 1;}
                return fibonacci(n-1) +fibonacci(n-2);
            }
            return n;
    
        }
    
        public static void main(String[] args) {
            System.out.println(fibonacci(0));
            System.out.println(fibonacci(1));
            System.out.println(fibonacci(2));
            System.out.println(fibonacci(3));
            System.out.println(fibonacci(1000000));
            // java.lang.StackOverflowError
        }
    }
    
    

    结果:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kXQkjtgK-1588037891688)(七、你了解Java的内存模型吗.assets/image-20200426185224796.png)]

    解决方法是限制递归次数,或者直接用循环解决。

    还有就是,由JVM管理的虚拟机栈数量也是有限的,也就是线程数量也是有限定。

    由于栈帧在方法返回后会自动释放,所有栈是不需要GC来回收的。

    1.3、本地方法栈

    • 与虚拟机栈相似,主要作用于标注了native的方法

    1.4、元空间(MetaSpace)

    元空间(MetaSpace)在jdk1.7之前是属于永久代(PermGen),两者的作用就是记录class的信息,jdk1.7中,永久代被移入堆中解决了前面版本的永久代分配内存不足时报出的OutOfMemoryError,元空间的前身就是方法区,jdk1.8之后元空间替代了永久代

    • 元空间使用本地内存,而永久代使用的是jvm的空间
    • 运行时常量池
      • 在加载类和接口到虚拟机后,就会创建对应的运行时常量池
      • JVM为每个已加载的类型(类或接口)都维护了一个常量池,池中的数据项就像数组项一样,通过索引访问。
      • 运行时常量池中包含多种不同的常量,包含编译期就已经明确的数值字面量,包括到运行器解析后才能够获得的方法或者字段引用,此时不再是常量池中的符号地址了,这里就会换成了真实地址。
      • 运行常量池,相对于Class文件常量池的另一重要的特征是:具备动态性。

    1.4.1、MetaSpace相比PermGen的优势

    • 字符串常量池存在永久代中,容易出现性能问题和内存溢出(空间大小不如元空间)
    • 类和方法的信息大小难以确定,给永久代的大小指定带来了困难
    • 永久代会为GC带来不必要的复杂性
    • 方便HotSpot与其他JVM如Jrockit的集成

    1.5、Java堆(Heap)

    • 对象实例的分配区域,实例在此处分配内存
    • java堆可以处于不连续的物理空间中,只要逻辑上是连续的即可
    • 是GC管理的主要区域,按照GC分代回收的方法,java堆又分为新生代老生代快速了解GC

    二、JVM三大性能调优参数 -Xms -Xmx -Xss的含义

    • -Xss:规定了每个线程虚拟机栈(堆栈)的大小(一般情况下256k足够)
    • -Xms:堆的初始值
    • -Xmx:堆能达到的最大值

    三、Java内存中堆和栈的区别——内存分配策略

    需要先了解

    • 静态存储:编译时确定每个数据目标在运行时的存储空间需求,不允许有可变的程序存在,比如循环
    • 栈式存储:数据区需求在编译时未知,运行时模块入口前确定。存储局部变量,定义在方法中的都是局部变量,所以,方法先进栈,创建栈帧等操作,方法一旦返回,即变量离开作用域,则栈帧释放,变量也会释放。(生命周期短)
    • 堆式存储:编译时或运行时模块入口都无法确定,动态分配。堆存储的是数组和对象,存储结构复杂,所需空间更多,哪怕是实体中的一个属性数据消失,这个实体也不会消失。(生命周期长)

    区别

    • 管理方式:栈自动释放,堆需要GC
    • 空间大小:栈比堆小
    • 碎片相关:栈产生的碎片远小于堆
    • 分配方式:栈支持静态和动态分配,而堆仅支持动态分配
    • 效率:栈的效率比堆高,堆更灵活
    • 联系:引用对象、数组时,栈里面定义变量保存堆中目标的首地址
      在这里插入图片描述

    四、元空间、堆、线程独占部分间的联系——内存角度

    我们来看下面这个例子:

    public class HelloWord {
        private String name;
    
        public void sayHello() {
            System.out.println("Hello " + name);
        }
        
        public void setName(String name) {
            this.name = name;
        }
    
        public static void main(String[] args) {
            int a = 1;
            HelloWord hw = new HelloWord();
            hw.setName("test");
            hw.sayHello();
        }
    }
    

    以下是各个部分包含的内容:
    在这里插入图片描述

    • 元空间里面存着类的信息,比如方法、变量
    • java堆中存放对象实例
    • 线程独占:用来保存变量的值即变量的引用、对象的地址引用,记录行号,用来记录代码的执行

    五、不同JDK版本之间的intern()方法的区别——JDK6 VS JDK6+

    说到这里我们不得不提一下String.intern()方法在jdk版本变更中的不同

    String s = new String("a");
    s.intern();
    

    JDK6:当调用intern方法时,如果字符串常量池先前已创建出该字符串对象,则返回池中的该字符串的引用。否则,将此字符串对象添加到字符串常量池中,并且返回该字符串对象的引用。

    JDK6+:当调用intern方法时,如果字符串常量池先前已创建出该字符串对象,则返回池中的该字符串的引用。否则,如果该字符串对象已经存在于Java堆中,则将堆中对此对象的引用添加到字符串常量池中,并且返回该引用;如果堆中不存在,则在池中创建该字符串并返回其引用

    我们看一个例子:

    jdk1.8

    public class InternDifference {
        public static void main(String[] args) {
            String s = new String("a"); // 会先根据字面量在池中创建一个"a"字符串,
            // 然后new的时候,在堆中创建一个"a",s——>堆中"a"
            s.intern(); // intern的时候,因为该对象已经存在于堆中,于是,想要将堆中对此对象的引用添加到池中
            // 但是池中此时已经存在"a",且不是堆中这个对象的引用,是独立存在的,intern无法创建引用进去
            String s2 = "a"; // 池中有"a",便直接引用池中的"a",s2——>池中"a"
            System.out.println(s == s2); // 两者的指向不同,故结果为false
    
            String s3 = new String("a") + new String("a"); // 两个括号中的字面量原本都是要在池中创建"a"的,但是上面的
            // 例子中,已经在池中创建了"a",故这里只会在堆中创建aa对象,s3指向堆中的对象
            s3.intern(); // intern时,发现池中并没有aa,于是将堆中对此对象的引用添加到字符串常量池中,然后池中就会有堆中"aa"对象的引用
            String s4 = "aa"; // 这里字面量创建的时候,发现池中有aa,则s4直接指向池中的"aa"
            System.out.println(s3 == s4); // 但是池中的"aa"实际上是对堆中对象的引用,所以两者实际上都是指向堆中对象,结果为true
        }
    }
    
    // 结果
    false
    true
    

    jdk1.6

    public class InternDifference {
        public static void main(String[] args) {
            String s = new String("a"); // 和上边一样,这里用引号声明了"a"字符串,会在常量池中先创建"a"
            // 然后new String()会在堆中创建对象
            s.intern(); // intern原本是想要将"a"直接复制一份到常量池中,但是池中已经有了,池中的也是独立存在的,故不能放副本
            String s2 = "a"; // s2字面量创建的时候发现池中有"a",故直接引用常量池中的"a"
            System.out.println(s == s2); // 根据上边的分析,结果肯定为false
    
            String s3 = new String("a") + new String("a"); // 和之前一样,先是想要创建声明的"a",但是池中已经有了上边的"a"
            // 故不会创建,只能直接new String创建生成"aa",s3指向堆中对象
            s3.intern(); // intern时发现池中没有"aa",故会放一个副本到常量池中(注意不是对堆中对象的引用)
            String s4 = "aa"; // 这里创建的时候发现池中已经有"aa",于是直接引用池中"aa"
            System.out.println(s3 == s4); // s3引用堆中的,s4引用池中的,故为false
        }
    }
    
    // 结果
    false
    false
    

    如有不对,请大家下方评论区指正,谢谢

    展开全文
  • 文章目录标题挥发性内存分2种,SRAM和DRAM主内存子系统channel 和 DIMMrank 和 chipbank、row、column内存的读写方式越多越好,加速读写能力 bank、rank、channel这些关于内存的名词是否已困绕许久,疑似了解却又说...

    本文转载来自:

    其它内容参考:

    个人理解的几点,先记录在这。

    • DDR,全称Double Data Rate,双数据速率。即上下时钟沿采样。
    • 双通道,是指两个channel,每个channel有单独控制器。比如SOC/CPU的ddr接口是64bit位宽,两个channel都是32bit位宽即可。因为依赖channel独立DDR控制器,可以并行采样,互不干扰,所以能达到双倍DDR位宽效果。台式机都是采用双通道DDR。
    • 为什么SOC不用双通道DDR技术?个人理解,管脚多了,布线复杂,功耗也会上去。没有便携,小型化需求,成本比重等考虑是可以用双通道的。
    • 本文没说DIMM和rank的区别。DIMM是插槽技术,rank是指8个chip芯片颗粒组合而成,与CPU/SOC DDR位宽保持一致的。

    转载正文

    bank、rank、channel这些关于内存的名词是否已困绕许久,疑似了解却又说不出个所以然来。 就让我们一步步拆解内存的面纱,从架构到读写方式逐步揭开内存的秘密。

    标题挥发性内存分2种,SRAM和DRAM

    RAM(Ramdom Access Memory)随机存取内存,之所以称作「随机存取」,是因为相较于早期的线性储存媒体(磁带)而言,因为磁带的存取是线性的,存取时间会依目前磁带位置和欲存取位置的距离而定,需转动磁带至应有的位置,距离越长、转得越久、存取时间也就越久。 而 RAM 没有这种烦恼,存取时间为固定值,不会因为数据在内存的位置而影响存取时间。

    而 RAM 在电脑里又可大致上分为 2 种:SRAM 和 DRAM,两者的基础原理差不多,都是将电荷储存至内部,藉由改变不同的电荷储存 0 或是 1。 SRAM(Static Random Access Memory)静态随机存取内存和DRAM(Dynamic Random Access Memory)有着几点不同,SRAM的结构较复杂、单位面积的容量较少、存取速度快,DRAM则是构造简单、单位面积内的容量较多、存取时间较SRAM慢,同时DRAM也因为构造较简单的关系, 储存的电荷会随着时间渐渐消失,因此需要有个再充电(Refresh)的动作保持电容储存的数据。
    SRAM 单一位储存区的构造
    ▲SRAM 单一位储存区的构造

    在这里插入图片描述
    ▲DRAM 单一位储存区的构造。

    由图中SRAM和DRAM构造可得知,SRAM采用正反器(flip-flop)构造储存,DRAM则是采用电容储存。 因为 SRAM 和 DRAM 种种的特性不同,SRAM 适合作为暂存器和 CPU 缓取使用,DRAM 则是适合做为主内存或是其他设备间的快取使用。

    挥发与非挥发性内存
    挥发性存储器(Volatile Memory)和非挥发性内存(Non-Volatile Memory)之间的差异在于,断电之后是否可保存内部资料,挥发性存储器的数据会随着失去电力供应而消失,而非挥发性内存依然可以保有内部资料。

    挥发性内存包含了SRAM和DRAM,而非挥发性内存包含ROM(Read-Only Memory)和Flash Memory闪存。

    主内存子系统

    DRAM 由于制造简单、高密度,作为电脑内部的主内存再适合不过了。 但是由于主内存摆放在CPU之外,从工厂出来的晶粒需要封装和组合之后才可和CPU连结,因此从CPU至DRAM晶粒之间依据层级由大至小为channel>DIMM>rank>chip>bank>row/column,接下来就一一说明这些部分。
    在这里插入图片描述
    ▲主内存由大至小,由上往下可做这样的拆分。
    在这里插入图片描述
    ▲主内存从 channel 至 chip 的相对应关系。
    在这里插入图片描述
    ▲chip 往下拆分为 bank。
    在这里插入图片描述
    ▲bank 往下拆就是 1 个个的储存单元,横向 1 排称之为 row,直向 1 排称之为 column,每排 column 的下方都有个 row buffer,用以暂存读出来的 row 排资料。

    在这里插入图片描述
    ▲单一 DRAM 芯片的内部功能区块图(图片取自Micron)。

    channel 和 DIMM

    从内存控制器出来之后,最先遇到的就是 channel,每个 channel 需要配有 1 组内存控制器、2 个 channel 配置 2 组… 以此类推。 而每个 channel 中能够拥有许多组 DIMM(Dual In-line Memory Module),DIMM 也就是目前使用者能够在市场上买到的内存模块,因为多年前的主板必须购买内存颗粒(chip)直接插在主板上,而后发展出 SIMM(Single In-line Memory Module),将多组内存颗粒焊在 1 片电路板上, 成为内存模块,再将此电路板插在主板上。 接着为了增加数据吞吐量,将 1 条内存模块的带宽从 SIMM 的 32bit 改换成 DIMM 的 64bit,这设计依然沿用至今。

    从内存颗粒过度到 SIMM 的时代,坊间出现了替用户将内存颗粒焊到 SIMM 电路板上的服务,因为当时内存非常昂贵,花一些小钱就可以把内存延用至新的电脑上。

    rank 和 chip

    rank 指的是链接到同 1 个CS(Chip Select)的内存颗粒 chip,内存控制器能够对同 1 rank 的 chip 进行读写操作,而在同 1 rank 的 chip 也分享同样的控制信号。 以目前的电脑来说,因为 1 组 channel 的宽度为 64bit,所以能够同时读写 8byte 的数据,如果是具有 ECC 功能的内存控制器和 ECC 内存模块,那么 1 组 channel 的宽度就是 72bit。

    在这里插入图片描述
    ▲rank 1 和 rank 2 共享同组 address/comand 讯号线,利用 chip select 线选择欲读取或是写入的那一组,之后将资料经由 MUX 多工器送出。

    有些人会有错误观念,以 chip 的数量或是以内存模块的单、双面进行 rank 的判断,但其实要以内存控制器和内存颗粒的规格进行判断,目前家用 PC 的内存控制器通道绝大部分都是 64bit 宽,内存颗粒则是 8bit 宽,因此 8 颗并联即可满足内存控制器的需求,也就是 1 组 rank。 但偶尔也有以 16bit 宽的内存颗粒制成的内存模块,此时 4 个 chip 就是 1 组 rank。

    这在采用Intel H61/H81芯片组和传统单channel的主板时须特别注意,因为Intel限制H61/H81每个 channel仅能支持2组 rank,而不是4组 rank,部分主板每个 channel 又 做了 2 组内存模块插槽,造成部分用户同组 channel 放入 2 条内存模块时能够识别全部的内存容量(双面单 rank 的内存模块),部分用户则是仅能识别一半的容量(双面双 rank 的内存模块)。

    bank、row、column

    bank 再往下分拆就是实际储存位元的电路,一般来说横向选择排数的线路称为 row(row enable、row select、word line),直向负责传递讯号的线路为column(bitline),每组 bank 的下方还会有个 row buffer(sense amplifier),负责将独出的 row 资料暂存,等待 column 地址送到后输出正确的位,以及判断储存的数据是 0 还是 1。
    在这里插入图片描述
    ▲1 个 bank 的读取操作。
    在这里插入图片描述
    ▲1 个 bank 的写入操作。

    内存的读写方式

    上图标明了内存的读写方式,读取时首先内存控制器会将 1 组地址由地址线传到内存上,控制线跟着传送控制信号;如果是多 rank 的安装情形,CS 也会送出对应的讯号选择目标 rank。 接着由于每个 rank 由许多 chip 组成,1 个 chip 仅负责部分的数据读取,chip 接收到地址信号后,将地址丢入内部的 row/column 解码器找出相对应的 bank 地址(每家每 款产品的内部 bank 组合有可能不同,因此对应也会有所不同),接着开启 row 线,同 1 排 row 的内部数据就会流到 row buffer 内部,row buffer 判断信号为 0 或是 1 之后就输出数据。

    写入时除了地址资料外,还会传送欲写入的资料至芯片内部的 input buffer,同样的也是依照 row/column 解码器找出对应位置之后写入。
    在这里插入图片描述
    ▲内存控制器和 DIMM 之间线路的关系。

    越多越好,加速读写能力

    家用计算机的内存控制器已经进入双通道内存控制器多年,加速原理为增加数据总线宽度,达到同时读写更多数据的能力。

    另一种增加带宽的方法就是减少延迟,利用多个 chip 或是 bank 达成。 一般的内存读取延迟为命令下达+内存读取延迟+输出数据,如果命令下达延迟为 2ns、内存读取延迟为 10ns、输出数据延迟为 2ns,那么读取 2 笔资料的总延迟就会是(2+10+2)×2=24ns。

    如果现在能够将数据拆分至2颗内存上,那么2笔读取延迟将降低至16ns,因为不需等到前笔资料读取完成才发出下一笔的读取命令,在第一笔数据进入内存读取时即可发出。 这种概念也可应用到目前最夯的SSD上,较多CE(Chip Enable)封装的闪存芯片,通常都比较少CE封装的芯片来得快。

    在这里插入图片描述
    ▲由时序图可得知,下方此种尽量分拆内存空间的作法,可大幅减少延迟。

    展开全文
  • 10分钟看懂内存的实现原理

    千次阅读 多人点赞 2019-11-06 13:57:46
    内存最小单位是一些类似于二极管这样的东西,它能存储一个电状态,高或低,可表示1或0; -这些单元经过组织起来保存数据,组织的方法是8个编成一个字节,4个字节一个字,每组数据都可以读写; -这些单元按照顺序排放...
  • 内存与cpu工作原理

    千次阅读 2017-05-03 22:25:47
    内存:通电状态下进行数据存储   cpu内部大致结构 程序控制器(CPU的控制中心) 职责: 1 分析或解释 指令 2 根据或析与解释结果向其他组件发出命令 3 控制cpu的工作进度和工作方式   当一指令进入...
  • 计算机原理(3)-内存工作原理

    千次阅读 2018-01-19 22:21:48
    CPU和内存是计算机中最重要的两个组件,前面已经知道了CPU是如何工作的,上一篇也介绍了内存采用的DRAM的存储原理。CPU工作需要知道指令或数据的内存地址,那么这样一个地址是如何和内存这样一个硬件联系起来的呢?...
  • JVM内存结构

    千次阅读 2022-04-06 20:59:07
    JVM内存结构 JVM的内存结构大致分为五个部分,分别是程序计数器、虚拟机栈、本地方法栈、堆和方法区。除此之外,还有由堆中引用的JVM外的直接内存。 下面将展开讲解这五个部分。 程序计数器 程序计数器(Program ...
  • 机械硬盘的存储结构及原理

    千次阅读 2019-06-25 13:06:58
    故而本博客主要对机械硬盘的结构原理进行讲解。 硬盘是由很多的盘片组成,而其存储信息的方式就是通过盘片表面的磁性物质来存储数据。把盘片放在显微镜下放大,可以看到盘片表面是凹凸不平的,凸起的地方被...
  • 内存的物理结构和工作原理

    千次阅读 2014-04-22 17:06:42
    内存的物理结构和工作原理 作者:xiaofeng 来源:PConline 发布时间:2012-11-01 点击数:1163  内存也叫主存,是PC系统存放数据与指令的半导体存储器单元,也叫主存储器(Main Memory),通常分为只读...
  • RabbitMQ数据存储结构及原理

    千次阅读 2020-10-28 21:50:33
    持久化消息在到达队列时写入磁盘,同时会内存中保存一份备份,当内存吃紧时,消息从内存中清除。这会提高一定的性能。 非持久化消息一般只存于内存中,当内存压力大时数据刷盘处理,以节省内存空间。 RabbitMQ存储层...
  • 硬盘内部硬件结构和工作原理详解

    万次阅读 多人点赞 2018-05-07 09:19:26
    硬盘的外部物理结构 一般硬盘正面贴有产品标签,主要包括厂家信息和产品信息,如商标、型号、序列号、生产日期、容量、参数和主从设置方法等。这些信息是正确使用硬盘的基本依据,下面将逐步介绍它们的含义。 硬盘...
  • JVM内存结构概述

    千次阅读 2019-08-20 23:32:58
    本节将会介绍一下JVM的内存结构,JVM运行时数据区的各个组成部分:堆,方法区,程序计数器,Java虚拟机栈,本地方法栈,还会对Java堆的分代划分做个简单的介绍。 目录 前言 JVM是什么 JVM内存结构概览 运行时...
  • 内存条是如何存储数据的?

    千次阅读 2021-07-28 00:12:35
    在计算机的组成结构中,有一个很重要的部分,就是存储器。存储器是用来存储程序和数据的部件,对于计算机来说,有了存储器,才有记忆功能,才能保证正常工作。存储器的种类很多,按其用途可分为主存储器和辅助存储器...
  • 计算机原理结构

    千次阅读 2021-11-14 10:45:46
    现代计算机基本硬件结构4.CPU内部结构划分1.控制单元2.运算单元3.存储单元5.计算机硬件多CPU架构1.多CPU2.CPU多核3.CPU寄存器4.CPU缓存5.内存1.CPU读取存储器数据过程2.多线程环境下存在的问题1.缓存一致性问题2....
  • 数据库索引的数据结构原理介绍

    千次阅读 2019-01-20 21:19:14
    当我们要查询表中数据时,这时就要拿着查询条件一逐一的与数据库中的数据进行比较,如果匹配到的数据正好是最后一,这样就把所有的数据都匹配了一遍。如果数据库中只有几百数据,这样的查询或许不会让你...
  • MySQL索引背后的数据结构及算法原理

    千次阅读 多人点赞 2018-03-20 20:45:22
     在编程领域有一句人尽皆知的法则“程序 = 数据结构 + 算法”,我个人是不太赞同这句话(因为我觉得程序不仅仅是数据结构加算法),但是在日常的学习和工作中我确认深深感受到数据结构和算法的重要性,很多东西,...
  • DDR3基本概念1 - 存储单元结构原理

    千次阅读 多人点赞 2019-02-28 19:47:07
    一个基本存储单元结构图如下图, storage capacitor为一个基本存储单元,当access transitor被选通时,可读可写: 一个4行3列的DDR 存储器如下图所示: 上图中蓝色的为bit line。相邻行的对应bit的bit line之间...
  • 计算机组成原理 这门学科告诉你什么是计算机。 首先,我们可以把计算机分解成最原始的部件——晶体管。晶体管是一种半导体材料,其最重要的作用就是半导:可以通过电流的变化,实现电路的切换。比如计算机最基础的与...
  • RoaringBitmap数据结构及原理

    万次阅读 多人点赞 2017-10-25 15:56:14
    BitmapContainer是一横线,始终占用8kb RunContainer比较奇葩,因为和数据的连续性关系太大,因此只能画出一个上下限范围。不管数据量多少,下限始终是4字节;上限在最极端的情况下可以达到128kb。 ...
  • redis的5种数据结构及其底层实现原理

    万次阅读 多人点赞 2020-10-21 19:55:43
    Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(无序集合)zset(有序集合)。 在秒杀项目里,我用过redis的Set和Hash结构: String:一个 key 对应一个字符串,string是Redis 最...
  • JVM内存结构和Java内存模型别再傻傻分不清了

    万次阅读 多人点赞 2020-03-04 20:53:30
    JVM内存结构和Java内存模型都是面试的热点问题,名字看感觉都差不多,网上有些博客也都把这两个概念混着用,实际上他们之间差别还是挺大的。 通俗点说,JVM内存结构是与JVM的内部存储结构相关,而Java内存模型是与多...
  • 虚拟存储器的实现思想就是将内存作为辅存的缓存,使得计算机系统拥有了 主存+辅存(交换空间) 大小的存储空间,同时也拥有了接近于主存的访问速度。 局部性原理 虚拟存储器的核心思路是根据程序运行时的局部性原理...
  • MongoDB体系结构与底层原理前言MongoDB体系结构NoSQL 和 MongoDBMongoDB 和RDBMS(关系型数据库)对比什么是BSONBSON在MongoDB中的使用MongoDB索引Index索引类型MongoDB 索引底层实现原理分析MongoDB架构MongoDB逻辑...
  • 内存条的逻辑BANK和RANK(物理BANK)概念

    万次阅读 多人点赞 2019-10-02 10:31:04
    内存条的逻辑BANK和RANK(物理BANK)概念 在内存上有一个参数:2R X16,1R X16, 1R X8….. 这里的R就是Rank 既物理BANK,X16,X8,是指芯片位宽 何谓内存BANK: 内存的BANK其实分为两部分,逻辑BANK和物理BANK。 ...
  • volatile实现原理分析
  • 存储器原理

    千次阅读 2021-07-23 03:03:06
    导读:数字系统中可对二进制数据进行存储的是存储器,FIFO、RAM等位于集成电路中可完成存储功能的是存储器,TF条、内存条等存储设备也是存储器。存储器已广泛存在于我们的生活中且为我们的生活提供诸多便利,接下来...
  • 操作系统对内存的管理 没有内存抽象的年代 ...不难想象,这种内存操作方式使得操作系统中存在多进程变得完全不可能,比如MS-DOS,你必须执行完一指令后才能接着执行下一。如果是多进程的话,由于直接操作物理...
  • DRAM的结构原理剖析

    千次阅读 2019-10-23 18:27:43
    由此可知:Rank其实就是一组内存颗粒位宽的集合,也可以叫Chips,在PCB上,往往把一面上的内存颗粒组成一个Rank,另一面是另外一个Rank(假若有的话),这样也可以将Rank理解内存条的Side(面)。具体说,当颗粒位宽×...
  • 深入理解JVM的内存结构及GC机制

    万次阅读 多人点赞 2017-11-23 02:12:38
    一、前言 JAVA GC(Garbage Collection,垃圾回收)机制是区别C++的一个重要特征,C++需要开发者自己...但这并不意味着我们不用去理解GC机制的原理,因为如果不了解其原理,可能会引发内存泄漏、频繁GC导致应用卡顿

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 248,138
精华内容 99,255
热门标签
关键字:

内存条的结构及原理

友情链接: one bubble free field.zip