精华内容
下载资源
问答
  • Windows7的任务管理器(以中文版为例)里面"进程"Tab页的列里面跟内存相关的展示项有...譬如什么工作集,专用工作集等等,另外像其它的一些常用工具,譬如ProcessExplorer里面可能又是叫Working Set,Private Bytes等等

    内存工作设置(工作集)、提交大小概念简述

    前言

    Windows7的任务管理器(以中文版为例)里面"进程"Tab页的列里面跟内存相关的展示项有7项(分页池和非页面缓冲池跟内核内存有关,暂不讨论),做软件工程师多年,大家真的懂任务管理器中这些内存相关的列吗?譬如什么工作集,专用工作集等等,另外像其它的一些常用工具,譬如ProcessExplorer里面可能又是叫Working Set,Private Bytes。

    另外像SetProcessWorkingSet,EmptyWorkingSet这些函数真的是洪水猛兽,完全不能使用吗?本文将简单讨论下这些问题,另外简单介绍下VMMap工具的使用。

    名词解释

    先进行一下名词解释,其实这个地方容易搞混的一个原因也是不同的工具的描述不一样,导致有些混乱,因此这里先把这些概念统一下,然后再进行解释(WS:Working Set的简称,none:表示无对应的显示选项)。

    Win7任务管理器中名称 Process Explorer中名称 VMMap中的名称
    工作设置(内存) Working Set Total WS
    内存(专用工作集) WS Private Private WS
    提交大小 Private Bytes Private(or Private Bytes)
    内存(共享工作集)* WS Shareable Shareable WS
    none WS Shared Shared WS
    none Virtrual Size Size
    none none Committed

    *Win10上面有共享工作集的展示

    工作设置(内存)/Working Set/Total WS: 专用(私有)工作集(当前进程独占)中的物理内存数量与进程正在使用且可以和其他进程共享的物理内存数量的总和,因此可以这么理解,该值就是该进程所占用的总的物理内存,但是这个值是由两部分组成,即"专用工作集"和"共享工作集"(Win10的任务管理器里面可以看到共享工作集)。在深入解析Windows操作系统里面是这样描述的:物理上驻留在内存中的那一部分子集称为工作集(Working Set)。

    峰值工作设置(内存): 进程的工作设置(内存)的最值,可以这么理解,因为工作设置(内存)是波动的,这个项专门记录最大的那个值。

    内存(专用工作集)/WS Private/ Private WS: 工作集的子集,它专门描述某个进程正在使用且无法与其他进程共享的物理内存值。这个值对于一个进程来说也是最重要的,它代表了一个进程到底独占了多少物理内存。

    内存(共享工作集)/ WS Shareable/ Shareable WS: 进程和可以和别的进程共享的物理内存值(注意:是可以共享的,不一定共享了)。比较常见的,譬如,加载系统的一些DLL所占用的物理内存,文件共享内存(文件映射),命名共享内存等等。

    WS Shared/ Shared WS: WS Shareable的子集,这部分是表示已经和别的进程共享的物理内存。

    提交大小/ Private Bytes/ Private: 给当前进程使用而保留的私有虚拟内存的数量,从名字里面的Private可以看出它是专有的,但是和上面的WS Private的区别在于,WS Private是纯物理内存,而Private Bytes实际上是虚拟内存的概念,是包含WS Private的,另外一部分是在换页文件(被从物理内存里面换出去了)里面,有些内存,虽然你提交,但是如果一直没有使用,也是在页面文件(换页文件:PageFile)里面。另外,多说一句,如果要查内存泄漏,可以关注这个值。

    Virtrual Size/Size: 当前进程使用的所有的虚拟内存空间,包含共享,非共享,物理,页面,甚至为程序保留但还未分配的内存。

    Committed: Virtual Size减去为程序保留的内存(未分配)。怎么理解为程序保留的但未分配的内存?就是告诉系统我要一块内存,但暂时还用不上,不过分配的地址得给我,系统就给程序一个不用的地址,但不分配内存,等程序真的要使用时(读写),就从页面或物理内存中分配出来映射到那个地址上。

    保留(预定)的内存: 将虚拟内存空间中线性地址0xXXXXXXXX-0xYYYYYYYY标记为预定状态,但是并没有分配实际的内存。这样的好处是我先预定一部分线性地址,以免后面进程空间中没有这么大的地址范围可用(一般来讲只有服务器上面这样用得多)。这样预定后,0xXXXXXXXX-0xYYYYYYYY这块地址就被占用,地址空间也是资源,虽然还没有分配任何内存。

    提交的内存: 系统从物理内存或者换页内存分配给进程的那一部分。这部分内存在虚拟内存的线性地址中是连续的,不过在物理内存或者换页内存中,不一定是连续的。提交但未使用的内存一般都在换页内存里面,只有去使用的时候,才会换到物理内存里面,这点要注意。

    换页内存: 也属于已经提交的内存,不过因为不常用,可能被系统置换到磁盘上面以节省物理内存,后面如果要使用会发生换页错误(缺页中断),再从磁盘上面置换到物理内存。

    缺页中断: 当程序要访问某个地址,系统发现这个地址不在物理内存里,就会产生中断,然后去读取页面文件,把页面文件中与内存相关的数据拷贝到物理内存,然后标记一下这个地址已经在物理内存中了,然后继续让程序运行。

    虚拟内存、物理内存和换页内存: (整个概念还是有一些复杂,这里只简单描述一下)虚拟内存一般是指整个进程用到的(虚拟)地址空间,之所以是虚拟的,因为中间被系统内存管理器抽象了一层,说到这里就牵涉到一个进程的虚拟内存空间的问题,win32下面一般应用层的虚拟地址空间是2G,然后从虚拟内存地址到物理内存有一个映射关系,这个映射是由内存管理器来完成的,对应用程序透明。而虚拟内存里面一般分成保留内存(压根就还没分配的,只是占了地址空间的坑),物理内存(正在使用)和换页内存(从物理内存换出去的,或者分配后一直未使用),另外物理内存和换页内存都属于已经提交的内存。

    分页池: 由内核或驱动程序代表进程分配的可分页内核内存的数量。可分页内存是可以写入其他存储媒介(例如硬盘)的内存。

    非分页缓冲池: 由内核或驱动程序代表进程分配的不可分页的内核内存的数量。不可分页的内存是不能写入其他存储媒介的内存。内核在处理低优先级的中断时,仍可以发生(处理)高优先级的中断,反过来则不行。缺页过程也是一个中断过程(缺页中断),那么就遇到了一个问题,即缺页中断和其他中断的优先级的问题。如果在高于缺页中断的中断优先级上再发生缺页中断,内核就会崩溃。所以在DISPATCH_LEVEL级别以上,绝对不能使用分页内存,一旦使用分页内存,就有发生缺页中断的可能,如果发生就会导致内核崩溃(蓝屏)。

    简单总结下:

    1、工作设置(内存),又叫工作集,即在物理内存中的数据的集合且等于专用工作集与共享工作集的和,Working Set = WS Private + WS Sharable。

    2、把所有的"工作集"相加后的值会大于任务管理器中提示的物理内存的使用值,因为工作集包含了共享工作集,这部分数据会重复计算。但是如果你只把专用工作集全部加起来又会发现小于任务管理器中提示的物理内存的使用值,因为你完全没有计算共享工作集。

    3、通俗的讲工作设置(内存)是程序占用的物理内存(包含与其他程序共享的一部分),内存专用工作集是程序独占的物理内存,提交大小(Private Bytes)是程序独占的内存(包含物理内存和换页内存)。

    4、Committed = VM Private Committed + VM Shareable Committed(VM:虚拟内存)

    5、Committed = Working Set + Page File Committed

    6、Private Bytes = WS Private + Page File Private

    介绍一个测试Windows极限的工具TestLimit,这个玩意功能挺多的,可以探测Windows系统物理内存,虚拟内存,分页&非分页内存,进程&线程,句柄,用户对象和GDI资源等的极限,这里用来探测一下内存的极限。以后有空了可以聊聊Windows其它一些系统资源的极限情况。

    命令行 含义 参考PID
    TestLimit -r 2048 -c 1 Reserve 2G内存 13520
    TestLimit -m 2048 –c 1 Commit 1G 内存, 但不访问这些内存 12448
    TestLimit –d 2048 –c 1 Commit 1G内存, 而且访问这些内存 13208

    *参考了网上的实验。

    根据PID进行对照,会发现,不同的情况影响的内存参数并不一样,大家可以自己做做这个实验体会下,对于系统内存机制会有更进一步的了解。

    内存优化的概念

    1、进行内存优化时,我们主要关注的指标有,工作设置(内存)/Working Set,内存(专用工作集)/WS Private,Private Bytes等几个,具体实践时要针对性优化。譬如要优化私有物理内存的使用,那么主要关注当前进程模块分配内存的特征和大小,找到主要的矛盾点。如果要优化共享内存的使用,除了关注命名共享内存的大小,文件映射之外,还要排除下进程加载的模块的大小是否有影响。

    2、高峰工作集(内存)这个指标一般关注比较小,也较少针对性的优化,主要是评估下内存使用是否平滑。在一些内存资源非常紧张的系统,要注意这个地方,防止内存高峰时,整个系统响应速度雪崩式下降。

    3、在进行内存优化时,首先要用相关工具进行内存分配的聚类和分析,然后再制订优化的方案和计划,首先要分清是内存使用不合理导致的问题,还是某些算法使用内存时可以进行技术上优化,不同的情况消耗的时间是完全不一样的。

    4、补充说明下经常被视为"洪水猛兽"的"刷内存",也就是调用SetProcessWorkingSet和EmptyWorkingSet(实际上是和使用特殊参数调用SetProcessWorkingSet类似)把强制系统把某个进程的部分物理内存置换到换页内存里面,其实Committed是不会变化的,但是短时间内Working Set会有明显的变化,为什么说是短时间内,因为虽然某些物理内存页临时置换到换页内存了,但是因为进程马上可能就用到的,又会立即被换出来,因此做完这个动作之后,关注下该进程的Page Fault值,会发现有明显的增量,反而可能影响系统性能。这两点(性能反而下降,假内存优化)也是这种方法被长期诟病的一些原因。不过,任何事情都有两面性,霸蛮点说,系统为什么提供这种API?完全没用的话,系统为什么不干掉。其实系统自己也在使用,虚拟内存管理器也会通过这个方法释放更多的物理内存给应用程序使用。当然,无节操的调用当然不行,什么一秒调用一次这种奇葩的操作,这样肯定会影响性能,那一般应该怎样使用呢?这里总结了几点,大家可以根据情况参考下:

    (1) 维持专用工作集(内存)和提交大小(Private Bytes)在一个合适的比例,不停的刷,物理内存600 KB,虚拟内存50M,这一看就不合理,一般来讲(个人经验),维持在1 : 2左右比较合理。实践中建议根据进程稳定之后的内存来设置这个值。

    (2) 建议在程序暂时不被使用的时候(例如最小化,闲时),或者刚刚完成了一件很消耗物理内存的动作之后,进行一次合理的设置。

    (3) 启动2~5分钟之后进行一次设置,这个跟启动时内存消耗的特点有关系,很多对象的生命周期都是和进程一样长,在初始化时,使用了很多STL,ATL或者自定义的对象,消耗了很多内存,但是这些对象可能就启动时用到了,后面大部分情况可能都用不到,但是它们的生命周期又很长,因此可以在启动一段时间之后,把这部分内存置换出去。另外,不建议在进程的生命周期中定时的去刷这个内存,即使要刷,也要降低刷的频率,甚至不刷。

    VMMap常用功能举例

    (略,后面有空再补充,这个工具本身就很简单)。

    参考文档

    1、https://www.cnblogs.com/walfud/articles/3256233.html Windows 任务管理器中的几个内存概念

    2、https://www.zhihu.com/question/19858114 Windows 7 里进程管理器里面的各列是什么含义?主要是和内存有关的内存-专用工作集,内存-工作集,内存-提交大小,这些之间有什么区别?

    3、https://www.cnblogs.com/awpatp/archive/2012/09/17/2688315.html Windows内存的一些知识点

    4、http://shashanzhao.com/archives/832.html windows任务管理器中的工作设置内存,内存专用工作集,提交大小详解

    5、https://superuser.com/questions/185318/process-explorer-not-showing-the-biggest-user-of-my-ram Process Explorer not showing the biggest user of my RAM VMMAP显示和process explorer不一样?

    6、http://www.cnblogs.com/georgepei/archive/2012/03/07/2383548.html 内存详解

    7、http://www.cnblogs.com/georgepei/archive/2012/03/07/2383445.html 你真的懂任务管理器中有关内存的参数Private(提交大小)和working set(工作设置)吗?

    8、http://blog.csdn.net/lantianjialiang/article/details/5620647 process explorer中的visual size vs working set; private bytes vs WS private

    9、http://www.cnblogs.com/awpatp/archive/2010/01/26/1656651.html Task Manager跟Performance Monitor的区别(Working set和Private bytes)

    10、https://social.microsoft.com/Forums/zh-CN/155e9b0e-8dd9-449a-960c-ce585850a049?prof=required 为什么任务管理器里面所有进程占用的内存加起来远远小于内存使用量?

    11、https://blogs.technet.microsoft.com/markrussinovich/2008/11/17/pushing-the-limits-of-windows-virtual-memory/ Pushing the Limits of Windows: Virtual Memory

    展开全文
  • 内存工作原理

    千次阅读 2015-11-29 14:18:51
    现代的PC(包括NB)都是以存储器为核心的多总线结构,即CPU只通过存储总线与主存储器交换信息(先在Cache里找数据,如果找不到,再去主存找)。输入输出设备通过I/O总线直接与主存储器...内部存储器简称内存,也可称
    现代的PC(包括NB)都是以存储器为核心的多总线结构,即CPU只通过存储总线与主存储器交换信息(先在Cache里找数据,如果找不到,再去主存找)。输入输出设备通过I/O总线直接与主存储器交换信息。在I/O设备和主存储器之间配置专用的I/O处理器。CPU不直接参与I/O设备与主存储器之间的信息传送。
        存储器分为内部存储器和外部存储器(或者叫主存储器和辅助存储器)。内部存储器简称内存,也可称为主存。从广义上讲,只要是PC内部的易失性存储器都可以看作是内存,如显存,二级缓存等等。外部存储器也称为外存,主要由一些非易失性存储器构成,比如硬盘、光盘、U盘、存储卡等等。
    内存作为数据的临时仓库,起着承上启下的作用,一方面要从外存中读取执行程序和需要的数据,另一方面还要为CPU服务,进行读写操作。所以主存储器快慢直接影响着PC的速度。下面我就从内存的原理开始谈起。
        一、原理篇
        内存工作原理
        1.内存寻址
        首先,内存从CPU获得查找某个数据的指令,然后再找出存取资料的位置时(这个动作称为“寻址”),它先定出横坐标(也就是“列地址”)再定出纵坐标(也就是“行地址”),这就好像在地图上画个十字标记一样,非常准确地定出这个地方。对于电脑系统而言,找出这个地方时还必须确定是否位置正确,因此电脑还必须判读该地址的信号,横坐标有横坐标的信号(也就是RAS信号,Row Address Strobe)纵坐标有纵坐标的信号(也就是CAS信号,Column Address Strobe),最后再进行读或写的动作。因此,内存在读写时至少必须有五个步骤:分别是画个十字(内有定地址两个操作以及判读地址两个信号,共四个操作)以及或读或写的操作,才能完成内存的存取操作。
        2.内存传输
        为了储存资料,或者是从内存内部读取资料,CPU都会为这些读取或写入的资料编上地址(也就是我们所说的十字寻址方式),这个时候,CPU会通过地址总线(Address Bus)将地址送到内存,然后数据总线(Data Bus)就会把对应的正确数据送往微处理器,传回去给CPU使用。
        3.存取时间
        所谓存取时间,指的是CPU读或写内存内资料的过程时间,也称为总线循环(bus cycle)。以读取为例,从CPU发出指令给内存时,便会要求内存取用特定地址的特定资料,内存响应CPU后便会将CPU所需要的资料送给CPU,一直到CPU收到数据为止,便成为一个读取的流程。因此,这整个过程简单地说便是CPU给出读取指令,内存回复指令,并丢出资料给CPU的过程。我们常说的6ns(纳秒,秒-9)就是指上述的过程所花费的时间,而ns便是计算运算过程的时间单位。我们平时习惯用存取时间的倒数来表示速度,比如6ns的内存实际频率为1/6ns=166MHz(如果是DDR就标DDR333,DDR2就标DDR2 667)。
        4.内存延迟
        内存的延迟时间(也就是所谓的潜伏期,从FSB到DRAM)等于下列时间的综合:FSB同主板芯片组之间的延迟时间(±1个时钟周期),芯片组同DRAM之间的延迟时间(±1个时钟周期),RAS到CAS延迟时间:RAS(2-3个时钟周期,用于决定正确的行地址),CAS延迟时间 (2-3时钟周期,用于决定正确的列地址),另外还需要1个时钟周期来传送数据,数据从DRAM输出缓存通过芯片组到CPU的延迟时间(±2个时钟周期)。一般的说明内存延迟涉及四个参数CAS(Column Address Strobe 行地址控制器)延迟,RAS(Row Address Strobe列地址控制器)-to-CAS延迟,RAS Precharge(RAS预冲电压)延迟,Act-to-Precharge(相对于时钟下沿的数据读取时间)延迟。其中CAS延迟比较重要,它反映了内存从接受指令到完成传输结果的过程中的延迟。大家平时见到的数据3—3—3—6中,第一参数就是CAS延迟(CL=3)。当然,延迟越小速度越快。
        二、外观篇
        由于笔记本的空间设计要求,笔记本内存比台式机内存条要窄,通常采用SO-DIMM模组规范,布线也比较紧凑,针脚也为标准的200Pin。我们经常看到的内存上,一般的元件有内存颗粒、电路板、SPD芯片、排阻(终结电阻)和针脚。下面我来分别介绍一下。
        1.颗粒
        内存颗粒就是大家平时见到内存上一个个的集成电路块。颗粒是内存的主要组成部分,颗粒性能可以说很大程度上决定了内存的性能,常见的颗粒有以下一些参数。
        A.厂商
        市场上生产内存颗粒的厂商主要有Hynix(现代电子),Samsung Electronics(***电子),Micro(美光),Infineon(英飞凌),Kingmax(胜创)等等。不过需要注意的一点是,“内存颗粒”和“内存条”是完全不同的两回事。能够生产内存颗粒的厂商全球没几个,而有了内存颗粒后内存条的生产就要简单得多,生产者自然要多得多。充斥市场的杂牌内存条与品牌内存条有着根本的区别,它们在成本上也有很多不同。Kingston、Kingmax、金邦等大的品牌内存条采用的都是符合Intel规定的6层PCB板和现代、***等内存大厂的内存颗粒,按照严格的工艺进行生产;而那些杂牌内存条虽然号称“***”、“现代”,其实就是一些小厂和作坊,他们拿来大厂内存颗粒的切割角料,焊到劣质的PCB板上就下了线,品质完全没有保证,而且经常与一些大的经销商结成联盟来生产和销售,价格波动也更容易受到渠道因素的影响。
        B.内存芯片类型
        内存芯片类型分SDRAM,DDR SDRAM,DDRⅡ SDRAM、SDRAM、DDR SDRAM和DDR SDRAM同出一门,都属SDRAM系,因此三者的颗粒在外观上不容易分辨,。但是由于采用的物理技术不同,三者在电路,延迟,带宽上还是有很大区别的,区分三者一般都是看颗粒的参数或者针脚和缺口位置,后面我会重点讲DDR和DDRⅡ技术。
        C.内存工艺和工作电压
        SDRAM内存工艺主要以CMOS为主,内存的工作电压和内存的芯片类型有很大关系,在JEDEC(Joint Electron Device Engineering Council 电子元件工业联合会)的规范中,SDRAM的工作电压是3.3V,DDR是2.5V,DDRⅡ是1.8V。
        D.芯片密度
        位宽及刷新速度芯片的密度一般都会用bit为单位进行表示(1B=8bit),比如16Mbit是16Mbit÷ 8bit=2MB也就是单颗芯片是2MB的。还有一个参数就是位宽,SDRAM系的位宽是64bit,采用多少个颗粒(一般为偶数)组成64bit也是不一样的。比如一个芯片是4bit的,那么要用16个同样的芯片才能组成64bits的,如果芯片是16bit那么只须4个就可以了。举个例子,256MB的内存可以用512bits÷8×4颗=256MB,4颗×16bit=64bit来组成,一般表示为512Mbits×16bit或64MB×16bit。刷新速度,内存条是由电子存储单元组成的,刷新过程对以列方式排列在芯片上的存储单元进行充电。刷新率是指被刷新的列的数目。两个常用的刷新率是2K和4K。2K模式能够在一定的时间内刷新较多的存储单元并且所用时间较短,因此2K所用的电量要大于4K。4K模式利用较慢的时间刷新较少的存储单元,然而它使用的电量较少。一些特殊设计的SDRAM具有自动刷新功能,它可自动刷新而不借助CPU或外部刷新电路。建立在DRAM内部的自动刷新,减少了电量消耗,被普遍应用于笔记本电脑。
        E.Bank
        内存的Bank一般分为物理Bank和逻辑Bank。物理Bank体现在SDRAM内存模组上,"Bank 数"表示该内存的物理存储体的数量。(等同于"行"/Row)。逻辑Bank表示一个SDRAM设备内部的逻辑存储库的数量。(现在通常是4个bank)。此外,对于主板,它还表示DIMM连接插槽或插槽组,例如Bank 0 或 Bank A。这里的Bank是内存插槽的计算单位,它是电脑系统与内存之间数据总线的基本工作单位。只有插满一个BANK,电脑才可以正常开机。举个例子,1个SDRAM线槽一个Bank为64bit,而老早以前的EDO内存是32bit的,必须要安装两根内存才能正常工作。主板上的Bank编号从Bank 0开始,必须插满Bank 0才能开机,Bank 1以后的插槽留给日后升级扩充内存用。
        F.电气接口类型
        般的电气接口类型与内存类型对应,如SDRAM是SSTL_3(3.3V)、DDR是 SSTL_2(2.5V)、DDRⅡ是SSTL_18(1.8V)。
        G.内存的封装
        现在比较普遍的封装形式有两种BGA和TSOP两种,BGA封装分FBGA,μBGA,TinyBGA(KingMAX)等等,TSOP分TSOPⅠ和TSOPⅡ。BGA封装具有芯片面积小的特点,可以减少PCB板的面积,发热量也比较小,但是需要专用的焊接设备,无法手工焊接。另外一般BGA封装的芯片,需要多层PCB板布线,这就对成本提出了要求。此外,BGA封装还拥有芯片安装容易、电气性能更好、信号传输延迟低、允许高频运作、散热性卓越等许多优点,它成为DDRⅡ官方选择也在情理之中。而TSOP相对来说工艺比较成熟,成本低,缺点是频率提升比较困难,体积较大,发热量也比BGA大。
        H.速度及延迟
        一般内存的速度都会用频率表示。比如大家常常看到的SDRAM 133、DDR 266、DDRⅡ 533其实物理工作频率都是133MHz,只是采用了不同的技术,理论上相当于2倍或4倍的速率运行,还有一种表示速度方法是用脉冲周期来表示速度,一般是纳秒级的。比如1/133MHz=7ns,说明该内存的脉冲周期是7ns。内存延迟我前面说过了,参数一般为4个,也有用3个的,数字越小表示延迟越小,速度越快。

        I.工作温度
        工作温度:工业常温(-40 - 85度);扩展温度(-25 - 85度)
        2.电路板
        电路板也称PCB版,是印刷电路板电子板卡的基础,由若干层导体和绝缘体组成的平板。电路图纸上的线路都蚀刻在其上,然后焊接上电子元件。由于所有的内存元件都焊在电路版上,因此电路板的布线是决定内存稳定性的重要方面,跟据Intel的规范,DDR内存必须使用6层PCB版才能保证内存的电气化功能和运行的稳定性。所以建议大家购买大厂的产品,不要使用来历不明的山寨货。
        3.SPD及SPD芯片
        SPD(Serial Presence Detect)— 串行存在侦测,SPD是一颗8针的EEPROM(Electrically Erasable Programmable ROM 电子可擦写程序式只读内存), 容量为256字节~2KB,里面主要保存了该内存的相关资料,如容量、芯片厂商、内存模组厂商、工作速度、是否具备ECC校验等。SPD的内容一般由内存模组制造商写入。支持SPD的主板在启动时自动检测SPD中的资料,并以此设定内存的工作参数。当开机时PC的BIOS将自动读取SPD中记录的信息,如果没有SPD,就容易出现死机或致命错误的现象。建议大家购买有SPD芯片的内存。

        4.排阻

        排阻,也称终结电阻(终结器)是DDR内存中比较重要的硬件。DDR内存对工作环境提出很高的要求,如果先前发出的信号不能被电路终端完全吸收掉而在电路上形成反射现象,就会对后面信号的影响从而造成运算出错。因此目前支持DDR主板都是通过采用终结电阻来解决这个问题。 由于每根数据线至少需要一个终结电阻,这意味着每块DDR主板需要大量的终结电阻,这也无形中增加了主板的生产成本,而且由于不同的内存模组对终结电阻的要求不可能完全一样,也造成了所谓的“内存兼容性问题”。由于DDR II内部集成了终结器,这个问题上得到了比较完美的解决。

        5.针脚(Pin)

        Pin-针状引脚,是内存金手指上的金属接触点。由于不同的内存的针脚不同,所以针脚也是从外观区分各种内存的主要方法。内存针脚分为正反两面,例如笔记本DDR内存是200Pin,那么正反两面的针脚就各为200÷2=100个。此外,有些大厂的金手指使用技术先进的电镀金制作工艺,镀金层色泽纯正,有效提高抗氧化性。保证了内存工作的稳定性

    三、技术篇

        1.DDR
    DDR技术

        DDR
    技术

        DDR SDRAM
    是双倍数据速率(Double Data RateSDRAM的缩写。从名称上可以看出,这种内存在技术上,与SDRAM有着密不可分的关系。事实上,DDR内存就是SDRAM内存的加强版。DDR运用了更先进的同步电路,使指定地址、数据的输送和输出主要步骤既独立执行,又保持与CPU完全同步;DDR使用了DLL(Delay Locked Loop,延时锁定回路提供一个数据滤波信号)技术,当数据有效时,存储控制器可使用这个数据滤波信号来精确定位数据,每16次输出一次,并重新同步来自不同存储器模块的数据。DDL本质上不需要提高时钟频率就能加倍提高SDRAM的速度,它允许在时钟脉冲的上升沿和下降沿读出数据,理论上使用原来的工作的频率可以产生2倍的带宽。同速率的DDR内存与SDR内存相比,性能要超出一倍,可以简单理解为133MHZ DDR="266MHZ" SDR。从外形体积上DDRSDRAM相比差别并不大,他们具有同样的尺寸和同样的针脚距离。DDR内存采用的是支持2.5V电压的SSTL2标准,而不是SDRAM使用的3.3V电压的LVTTL标准。但是DDR存在自身的局限性DDR只是在SDRAM基础上作简单改良,并行技术与生俱来的易受干扰特性并没有得到丝毫改善,尤其随着工作频率的提高和数据传输速度加快,总线间的信号干扰将造成系统不稳定的灾难性后果;反过来,信号干扰也制约着内存频率的提升——当发展到DDR400规范时,芯片核心的工作频率达到200MHz,这个数字已经非常接近DDR的速度极限,只有那些品质优秀的颗粒才能够稳定工作于200MHz之上,所以DDR标准就成了一种进一步提高内存速度的解决方法。

        DDR 
    技术

        DDR
    相对于DDR有三大技术革新,4位预取(DDR2位)、Posted CAS、整合终结器(ODT)、FBGA/CSP封装。要解释预取的概念,我们必须从内存的频率说起。大家通常说的内存频率其实是一个笼统的说法,内存频率实际上应细分为数据频率、时钟频率和DRAM核心频率三种。数据频率指的是内存模组与系统交换数据的频率;时钟频率则是指内存与系统协调一致的频率;而DRAM核心频率指的是DRAM内部组件的工作频率,它只与内存自身有关而不受任何外部因素影响。对SDRAM来说,这三者在数字上是完全等同的,也就是数据频率=时钟频率=核心频率;而DDR技术却不是如此,它要在一个时钟周期内传输两次数据,数据频率就等于时钟频率的两倍,但核心频率还是与时钟频率相等。由于数据传输频率翻倍(传输的数据量也翻倍),而内部核心的频率并没有改变,这意味着DDR芯片核心必须在一个周期中供给双倍的数据量才行,实现这一任务的就是所谓的两位预取(2bit Prefect)技术;DDR采用的4位预取。这项技术的原理是将DRAM存储矩阵的位宽增加一(两)倍,这样在一个时钟周期内就可以传输双(四)倍的数据,这些数据接着被转化为宽度为1/214)的两道数据流、分别从每个时钟周期的上升沿和下降沿传送出去。Posted CASDDR通过引入Posted CAS功能来解决带宽利用变低的问题,所谓Posted CAS,指的是将CAS(读/写命令)提前几个周期、直接插到RAS信号后面的一个时钟周期,这样CAS命令可以在随后的几个周期内都能保持有效,但读/写操作并没有因此提前、总的延迟时间没有改变。这样做的好处在于可以彻底避免信号冲突、提高内存使用效率,但它只有在读写极其频繁的环境下得到体现,若是普通应用,Posted CAS功能反而会增加读取延迟、令系统性能下降,因此我们可以根据需要、通过BIOSPosted CAS功能开启或关闭(关闭状态下DDR的工作模式就与DDR完全相同)。  芯片整合终结器,提高了内存工作的稳定性,增强的内存的兼容性。FBGA封装和CSP封装,封装虽然无法直接决定内存的性能,但它对内存的稳定工作至关重要。 FBGA封装是DDR的官方选择,FBGA属于BGA体系(Ball Grid Array,球栅阵列封装),前面已经讲过了。CSP封装最大的特点在于封装面积与芯片面积异常接近,两者比值仅有1.141,它也是目前最接近11理想状况的芯片封装技术。这样在同样一条模组中就可以容纳下更多数量的内存芯片,有利于提升模组的总容量。 

        2.
    双通道内存控制器技术

        所谓双通道
    DDR,简单来说,就是芯片组可以在两个不同的数据通道上分别寻址、读取数据。这两个相互独立工作的内存通道是依附于两个独立并行工作的,位宽为64-bit的内存控制器下,因此使普通的DDR内存可以达到128-bit的位宽,如果是DDR333的话,双通道技术可以使其达到DDR667的效果,内存带宽陡增一倍。双通道DDR有两个64bit内存控制器,双64bit内存体系所提供的带宽等同于一个128bit内存体系所提供的带宽,但是二者所达到效果却是不同的。双通道体系包含了两个独立的、具备互补性的智能内存控制器,两个内存控制器都能够在彼此间零等待时间的情况下同时运作。例如,当控制器B准备进行下一次存取内存的时候,控制器 A就在读/写主内存,反之亦然。两个内存控制器的这种互补天性可以让有效等待时间缩减50%,双通道技术使内存的带宽翻了一翻。双通道DDR的两个内存控制器在功能上是完全一样的,并且两个控制器的时序参数都是可以单独编程设定的。这样的灵活性可以让用户使用三条不同构造、容量、速度的DIMM内存条,此时双通道DDR简单地调整到最低的密度来实现128bit带宽,允许不同密度/等待时间特性的DIMM内存条可以可靠地共同运作。双通道DDR技术带来的性能提升是明显的,DDR266能够提供2.1GB/s的带宽,而双通道DDR266则能提供4.2GB/s的带宽。以此类推,双通道DDR333DDR400能够达到5.4GB/s6.4GB/s

        3.CPU
    集成内存控制器技术

        这是
    AMD公司提高CPU与内存性能的一项技术,这项技术是一种将北桥的内存控制器集成到CPU的一种技术,这种技术的使用使得原来,CPU-北桥-内存三方传输数据的过程直接简化成CPU与内存之间的单项传输技术,并且降低了它的延迟潜伏期,提高了内存工作效率。这么做得的目的是为了解放系统的北桥,众所周知,显卡也是通过北桥向CPU传输数据的,虽然说早在GeForce256时代就有了GPU的说法,但是随着现在游戏的进步,画面的华丽,不少数据还是需要CPU来做辅助处理的。这些数据传输到CPU必然要经过系统的北桥,由于AMD64系统将内存控制集成到主般中来了,所以压力减小的北桥便可以更好地为显卡服务。另外,缺少了中间环节,内存和CPU之间的数据交换显得更为流畅。但是这项技术也有缺点,当新的内存技术出现时,必须要更换CPU才能支持。这在无形间增加了成本。

        4.
    其他技术

        A.ECC
    内存

        全称
    Error Checkingand Correcting。它也是在原来的数据位上外加位来实现的。如8位数据,则需1位用于Parity检验,5位用于ECC,这额外的5位是用来重建错误的数据的。当数据的位数增加一倍,Parity也增加一倍,而ECC只需增加一位,当数据为64位时所用的ECCParity位数相同(都为。在那些Parity只能检测到错误的地方,ECC可以纠正绝大多数错误。若工作正常时,你不会发觉你的数据出过错,只有经过内存的纠错后,计算机的操作指令才可以继续执行。当然在纠错时系统的性能有着明显降低,不过这种纠错对服务器等应用而言是十分重要的,ECC内存的价格比普通内存要昂贵许多。

        B.
    UnBuffered Memory 内存

        (
    UnBuffered Memory,(不)带有缓存的内存条。缓存能够二次推动信号穿过内存芯片,而且使内存条上能够放置更多的内存芯片。带缓存的内存条和不带缓存的内存条不能混用。电脑的内存控制器结构,决定了该电脑上带缓存的内存还是上不带缓存的内存。

    展开全文
  • Windows工作内存

    千次阅读 2015-07-28 17:37:20
    Windows任务管理器默认情况下,“内存(私人工作集)”列处于选中状态。 私人工作集是工作集的一个子集,它是描述每个进程所使用的内存数量的技术术语。私人工作集专门描述了某个进程正在使用的且无法与其他进程共享...

    Windows任务管理器默认情况下,“内存(私人工作集)”列处于选中状态。


    内存 - 工作集:是私人工作集中的内存数量与进程正在使用且可以由其他进程共享的内存数量的总和。
    内存 - 峰值工作集:是进程所使用的工作集内存的最大数量。
    内存 - 工作集增量:是进程所使用的工作集内存中的更改量。
    内存 - 专用工作集:- 是工作集的一个子集,它是描述每个进程所使用的内存数量的技术术语。专用工作集专门描述了某个进程正在使用的且无法与其他进程共享的内存数量。
    内存 - 提交大小:是为某进程使用而保留的虚拟内存的数量。
    内存 - 页面缓冲池:是可以写入其他存储媒体(例如硬盘)的某个进程的认可虚拟内存数量。
    内存 - 非页面缓冲池:是无法写入其他存储媒体的某个进程的认可虚拟内存数量。


    一. SetProcessWorkingSetSize 的工作原理

    看看这个API                       SetProcessWorkingSetSize

    这是从MSDN摘下的原话

    Using the SetProcessWorkingSetSize function to set an application's minimum and maximum working set sizes does not guarantee that the requested memory will be reserved, or that it will remain resident at all times. When the application is idle, or a low-memory situation causes a demand for memory, the operating system can reduce the application's working set. An application can use the VirtualLock function to lock ranges of the application's virtual address space in memory; however, that can potentially degrade the performance of the system.

    使用这个函数来设置应用程序最小和最大的运行空间,只会保留需要的内存。当应用程序被闲置或系统内存太低时,操作系统会自动调用这个机制来设置应用程序的内存。应用程序也可以使用 VirtualLock 来锁住一定范围的内存不被系统释放。

    When you increase the working set size of an application, you are taking away physical memory from the rest of the system. This can degrade the performance of other applications and the system as a whole. It can also lead to failures of operations that require physical memory to be present; for example, creating processes, threads, and kernel pool. Thus, you must use the SetProcessWorkingSetSize function carefully. You must always consider the performance of the whole system when you are designing an application.

    当你加大运行空间给应用程序,你能够得到的物理内存取决于系统,这会造成其他应用程序降低性能或系统总体降低性能,这也可能导致请求物理内存的操作失败,例如:建立 进程,线程,内核池,就必须小心的使用该函数。

    ========================

    事实上,使用该函数并不能提高什么性能,也不会真的节省内存。

    因为他只是暂时的将应用程序占用的内存移至虚拟内存,一旦,应用程序被激活或者有操作请求时,这些内存又会被重新占用。如果你强制使用该方法来 设置程序占用的内存,那么可能在一定程度上反而会降低系统性能,因为系统需要频繁的进行内存和硬盘间的页面交换。


    BOOL SetProcessWorkingSetSize(
    HANDLE hProcess,
    SIZE_T dwMinimumWorkingSetSize,
    SIZE_T dwMaximumWorkingSetSize
    );


    将 2个 SIZE_T 参数设置为 -1 ,即可以使进程使用的内存交换到虚拟内存,只保留一小部分代码

    1 。当我们的应用程序刚刚加载完成时,可以使用该操作一次,来将加载过程不需要的代码放到虚拟内存,这样,程序加载完毕后,保持较大的可用内存。

    2.程序运行到一定时间后或程序将要被闲置时,可以使用该命令来交换占用的内存到虚拟内存。

    二. 区分物理内存、虚拟内存、Working Set(Memory)、Memory

    以下来自:http://blog.joycode.com/qqchen/archive/2004/03/17/16434.aspx

    这个问题在CSDN上碰到好几次,我每次都只给出了简单的答案:不要参考Task Manager的Mem Usage数据,那个数据的大小对程序性能没有直接影响。
    下面是我分析这问题的一些思路,希望对对这个问题感兴趣的朋友有所帮助

    Q: Is .NET Alone?
    A:
     Nope! 前面Saucer说过了,这不是.NET的问题,所有Windows程序都有类似的行为。例如下面的C程序:
    void main { while(1); }   //死循环,便于我们察看Task Manager
    初次运行在我的机器上Mem Usage是632K,把Console最小化以后再恢复,Mem Usage变成了36K。显然,这不是一个.NET独有的问题,而是Windows Memory Management的问题。那么和.NET的GC机制也不会有太大的关系——虽然问题的表现形式很容易让人联想到GC。

    Q: How much memory does my program use?
    A:
     回答这个问题并不容易。先来看看操作系统虚拟内存管理的一些基本概念:每个Windows进程都拥有4G的地址空间,但是你的机器显然没有4G的物理内存。在多任务环境下,所有进程使用的内存总和可以超过计算机的物理内存。在特定的情况下,进程的一部分可能会从物理内存中删除而被暂存在硬盘的文件里(pagefile),当进程试图访问这些被交换到pagefile里的内存的时候,系统会产生一个缺页中断(page fault),这时候Windows内存管理器会负责把对应的内存页重新从硬盘调入物理内存。
    在某个时间内,一个进程可以直接访问到的物理内存(不发生缺页中断)叫做这个进程的Working Set;而一个进程从4G的地址空间当中实际分配(commit)了的、可访问的内存称为Committed Virtual Memory。Committed VM可能存在于Page File当中,WorkingSet则一定位于物理内存。
    所以要回答上面的问题先要反问一句:What're you talking about? Physical Memory or Committed Memory?

    Q: What is this "Mem Usage" data?
    A:
     From Task Manager Help: In Task Manager, the current Working Set of a process, in kilobytes. 
    Mem Usage这个名字多少有些误导。它只表示这个进程当前占用的物理内存,也就是WorkingSet。WorkingSet不表示进程当前“占用”的所有虚拟内存,该进程可能还有一部分数据被交换到pagefile当中。这些数据只有在被访问的时候才会被加载到物理内存。
    Task Manager有另一列数据:VM Size,表示了一个进程分配的虚存(Committed Visual Memory)——实际的定义要比这个复杂一些,但这个定义对我们目前分析的问题已经足够了。以前面的C程序为例,在最小化前后的VM Size都是176K,并没有变化。
    所以,结论很简单:当一个Windows程序被最小化的时候,Windows内存管理器把该进程的WorkingSet减到最小(根据先进先出FIFO或者最近最少使用LRU),把大部分数据交换到pagefile里。这很容易理解:我们通常总是希望为前台的应用程序留出更多物理内存,从而具有更好的性能。当该程序从最小化恢复的时候,Windows也不会完全加载程序的所有虚存,只是加载了必要的部分。这也很容易理解:程序启动阶段的代码通常在启动之后很少访问(对.NET程序尤其如此,向fusion这样的模块在程序正常加载之后如果没有用到Reflection通常用不到)。

    Q: So, Do we want a smaller workingset, or a larger one?
    A:
     It depends. Conventional Wisdom tells us: The smaller, the better. 但是在虚存的问题上却没这么简单。如果WorkingSet太小,程序运行过程中会产生很多缺页中断,这会严重影响程序的性能。另一方面,WorkingSet太大会浪费“宝贵的”物理内存,降低整个系统的性能。 通常情况下(除非是对性能非常敏感的应用程序,并且你对Windows的内存管理了如指掌),建议不要在程序中自己调整WorkingSet的大小,而把这个任务交给Windows内存管理器。调整的方法Saucer有提到: SetProcessWorkingSetSize();

    Q: Final Question, Does my program really occupy that much physical memory?
    A:
     这个问题看上去土了点——那个数字明明白白的写在Task Manager里面。
    sam1111用vadump检查的结果显示进程WorkingSet减小的主要原因是很多DLL在从最小化恢复的时候没有被加载到物理内存。我们知道DLL的一个特点是代码共享,以NTDLL.DLL为例,整个Windows系统的几乎所有应用程序(具体地说,Win32子系统的所有程序)都需要引用NTDLL.DLL,如果每人一份,光这个文件就的占用几十兆内存。Windows地解决办法是只在物理内存中保存一份NTDLL.DLL的COPY,所有引用这个DLL的程序都把这一份COPY映射到自己的内存空间里面,共享NTDLL.DLL的代码段(每个进程的数据段仍然是独立的)。所以虽然NTDLL.DLL的大小被计算在你的程序的WorkingSet里面,但是从你的程序中去掉对这个DLL的引用并不会真的释放多少物理内存——你不用,别人还在用呢!
    所以,你的程序“独占”的物理内存远没有Mem Usage所表示的那么多,需要从Mem Usage里面扣除很多Shared Code Page (vadump里面可以看到)。

    结论?不要参考Task Manager的Mem Usage数据,那个数据的大小对程序性能没有直接影响。用Perfomence Monitor里面与.NET相关的Counter要容易、准确的多

    
    
    
    
    展开全文
  • Java内存模型是什么

    千次阅读 2019-03-12 17:21:22
    在介绍Java内存模型之前,先来看一下到底什么是计算机内存模型,然后再来看Java内存模型在计算机内存模型的基础上做了哪些事情。要说计算机的内存模型,就要说一下一段古老的历史,看一下为什么要有内存模型。 内存...

    为什么要有内存模型

    在介绍Java内存模型之前,先来看一下到底什么是计算机内存模型,然后再来看Java内存模型在计算机内存模型的基础上做了哪些事情。要说计算机的内存模型,就要说一下一段古老的历史,看一下为什么要有内存模型。

    内存模型,英文名Memory Model,他是一个很老的老古董了。他是与计算机硬件有关的一个概念。那么我先给你介绍下他和硬件到底有啥关系。

    CPU和缓存一致性

    我们应该都知道,计算机在执行程序的时候,每条指令都是在CPU中执行的,而执行的时候,又免不了要和数据打交道。而计算机上面的数据,是存放在主存当中的,也就是计算机的物理内存啦。

    刚开始,还相安无事的,但是随着CPU技术的发展,CPU的执行速度越来越快。而由于内存的技术并没有太大的变化,所以从内存中读取和写入数据的过程和CPU的执行速度比起来差距就会越来越大,这就导致CPU每次操作内存都要耗费很多等待时间。

    这就像一家创业公司,刚开始,创始人和员工之间工作关系其乐融融,但是随着创始人的能力和野心越来越大,逐渐和员工之间出现了差距,普通员工原来越跟不上CEO的脚步。老板的每一个命令,传到到基层员工之后,由于基层员工的理解能力、执行能力的欠缺,就会耗费很多时间。这也就无形中拖慢了整家公司的工作效率。

    可是,不能因为内存的读写速度慢,就不发展CPU技术了吧,总不能让内存成为计算机处理的瓶颈吧。

    所以,人们想出来了一个好的办法,就是在CPU和内存之间增加高速缓存。缓存的概念大家都知道,就是保存一份数据拷贝。他的特点是速度快,内存小,并且昂贵。

    那么,程序的执行过程就变成了:

    当程序在运行过程中,会将运算需要的数据从主存复制一份到CPU的高速缓存当中,那么CPU进行计算时就可以直接从它的高速缓存读取数据和向其中写入数据,当运算结束之后,再将高速缓存中的数据刷新到主存当中。

    之后,这家公司开始设立中层管理人员,管理人员直接归CEO领导,领导有什么指示,直接告诉管理人员,然后就可以去做自己的事情了。管理人员负责去协调底层员工的工作。因为管理人员是了解手下的人员以及自己负责的事情的。所以,大多数时候,公司的各种决策,通知等,CEO只要和管理人员之间沟通就够了。

    而随着CPU能力的不断提升,一层缓存就慢慢的无法满足要求了,就逐渐的衍生出多级缓存。

    按照数据读取顺序和与CPU结合的紧密程度,CPU缓存可以分为一级缓存(L1),二级缓存(L3),部分高端CPU还具有三级缓存(L3),每一级缓存中所储存的全部数据都是下一级缓存的一部分。

    这三种缓存的技术难度和制造成本是相对递减的,所以其容量也是相对递增的。

    那么,在有了多级缓存之后,程序的执行就变成了:

    当CPU要读取一个数据时,首先从一级缓存中查找,如果没有找到再从二级缓存中查找,如果还是没有就从三级缓存或内存中查找。

    随着公司越来越大,老板要管的事情越来越多,公司的管理部门开始改革,开始出现高层,中层,底层等管理者。一级一级之间逐层管理。

    单核CPU只含有一套L1,L2,L3缓存;

    如果CPU含有多个核心,即多核CPU,则每个核心都含有一套L1(甚至和L2)缓存,而共享L3(或者和L2)缓存。

    公司也分很多种,有些公司只有一个大Boss,他一个人说了算。但是有些公司有比如联席总经理、合伙人等机制。
    单核CPU就像一家公司只有一个老板,所有命令都来自于他,那么就只需要一套管理班底就够了。
    多核CPU就像一家公司是由多个合伙人共同创办的,那么,就需要给每个合伙人都设立一套供自己直接领导的高层管理人员,多个合伙人共享使用的是公司的底层员工。
    还有的公司,不断壮大,开始差分出各个子公司。各个子公司就是多个CPU了,互相之前没有共用的资源。互不影响。

    下图为一个单CPU双核的缓存结构。
    在这里插入图片描述
    随着计算机能力不断提升,开始支持多线程。那么问题就来了。我们分别来分析下单线程、多线程在单核CPU、多核CPU中的影响。

    **单线程。**cpu核心的缓存只被一个线程访问。缓存独占,不会出现访问冲突等问题。

    **单核CPU,多线程。**进程中的多个线程会同时访问进程中的共享数据,CPU将某块内存加载到缓存后,不同线程在访问相同的物理地址的时候,都会映射到相同的缓存位置,这样即使发生线程的切换,缓存仍然不会失效。但由于任何时刻只能有一个线程在执行,因此不会出现缓存访问冲突。

    **多核CPU,多线程。**每个核都至少有一个L1 缓存。多个线程访问进程中的某个共享内存,且这多个线程分别在不同的核心上执行,则每个核心都会在各自的caehe中保留一份共享内存的缓冲。由于多核是可以并行的,可能会出现多个线程同时写各自的缓存的情况,而各自的cache之间的数据就有可能不同。

    在CPU和主存之间增加缓存,在多线程场景下就可能存在缓存一致性问题,也就是说,在多核CPU中,每个核的自己的缓存中,关于同一个数据的缓存内容可能不一致。

    如果这家公司的命令都是串行下发的话,那么就没有任何问题。
    如果这家公司的命令都是并行下发的话,并且这些命令都是由同一个CEO下发的,这种机制是也没有什么问题。因为他的命令执行者只有一套管理体系。
    如果这家公司的命令都是并行下发的话,并且这些命令是由多个合伙人下发的,这就有问题了。因为每个合伙人只会把命令下达给自己直属的管理人员,而多个管理人员管理的底层员工可能是公用的。
    比如,合伙人1要辞退员工a,合伙人2要给员工a升职,升职后的话他再被辞退需要多个合伙人开会决议。两个合伙人分别把命令下发给了自己的管理人员。合伙人1命令下达后,管理人员a在辞退了员工后,他就知道这个员工被开除了。而合伙人2的管理人员2这时候在没得到消息之前,还认为员工a是在职的,他就欣然的接收了合伙人给他的升职a的命令。

    在这里插入图片描述

    处理器优化和指令重排

    上面提到在在CPU和主存之间增加缓存,在多线程场景下会存在缓存一致性问题。除了这种情况,还有一种硬件问题也比较重要。那就是为了使处理器内部的运算单元能够尽量的被充分利用,处理器可能会对输入代码进行乱序执行处理。这就是处理器优化。

    除了现在很多流行的处理器会对代码进行优化乱序处理,很多编程语言的编译器也会有类似的优化,比如Java虚拟机的即时编译器(JIT)也会做指令重排

    可想而知,如果任由处理器优化和编译器对指令重排的话,就可能导致各种各样的问题。

    关于员工组织调整的情况,如果允许人事部在接到多个命令后进行随意拆分乱序执行或者重排的话,那么对于这个员工以及这家公司的影响是非常大的。

    并发编程的问题

    前面说的和硬件有关的概念你可能听得有点蒙,还不知道他到底和软件有啥关系。但是关于并发编程的问题你应该有所了解,比如原子性问题,可见性问题和有序性问题。

    其实,原子性问题,可见性问题和有序性问题。是人们抽象定义出来的。而这个抽象的底层问题就是前面提到的缓存一致性问题、处理器优化问题和指令重排问题等。

    这里简单回顾下这三个问题,并不准备深入展开,感兴趣的读者可以自行学习。我们说,并发编程,为了保证数据的安全,需要满足以下三个特性:

    原子性是指在一个操作中就是cpu不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行。

    可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。

    有序性即程序执行的顺序按照代码的先后顺序执行。

    有没有发现,缓存一致性问题其实就是可见性问题。而处理器优化是可以导致原子性问题的。指令重排即会导致有序性问题。所以,后文将不再提起硬件层面的那些概念,而是直接使用大家熟悉的原子性、可见性和有序性。

    什么是内存模型

    前面提到的,缓存一致性问题、处理器器优化的指令重排问题是硬件的不断升级导致的。那么,有没有什么机制可以很好的解决上面的这些问题呢?

    最简单直接的做法就是废除处理器和处理器的优化技术、废除CPU缓存,让CPU直接和主存交互。但是,这么做虽然可以保证多线程下的并发问题。但是,这就有点因噎废食了。

    所以,为了保证并发编程中可以满足原子性、可见性及有序性。有一个重要的概念,那就是——内存模型。

    为了保证共享内存的正确性(可见性、有序性、原子性),内存模型定义了共享内存系统中多线程程序读写操作行为的规范。通过这些规则来规范对内存的读写操作,从而保证指令执行的正确性。它与处理器有关、与缓存有关、与并发有关、与编译器也有关。他解决了CPU多级缓存、处理器优化、指令重排等导致的内存访问问题,保证了并发场景下的一致性、原子性和有序性。

    内存模型解决并发问题主要采用两种方式:限制处理器优化和使用内存屏障。本文就不深入底层原理来展开介绍了,感兴趣的朋友可以自行学习。

    什么是Java内存模型

    前面介绍过了计算机内存模型,这是解决多线程场景下并发问题的一个重要规范。那么具体的实现是如何的呢,不同的编程语言,在实现上可能有所不同。

    我们知道,Java程序是需要运行在Java虚拟机上面的,Java内存模型(Java Memory Model ,JMM)就是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,保证了Java程序在各种平台下对内存的访问都能保证效果一致的机制及规范。

    提到Java内存模型,一般指的是JDK 5 开始使用的新的内存模型,主要由JSR-133: JavaTM Memory Model and Thread Specification 描述。感兴趣的可以参看下这份PDF文档(http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf)

    Java内存模型规定了所有的变量都存储在主内存中,每条线程还有自己的工作内存,线程的工作内存中保存了该线程中是用到的变量的主内存副本拷贝,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存。不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量的传递均需要自己的工作内存和主存之间进行数据同步进行。

    而JMM就作用于工作内存和主存之间数据同步过程。他规定了如何做数据同步以及什么时候做数据同步。

    在这里插入图片描述

    这里面提到的主内存和工作内存,读者可以简单的类比成计算机内存模型中的主存和缓存的概念。特别需要注意的是,主内存和工作内存与JVM内存结构中的Java堆、栈、方法区等并不是同一个层次的内存划分,无法直接类比。《深入理解Java虚拟机》中认为,如果一定要勉强对应起来的话,从变量、主内存、工作内存的定义来看,主内存主要对应于Java堆中的对象实例数据部分。工作内存则对应于虚拟机栈中的部分区域。

    所以,再来总结下,JMM是一种规范,目的是解决由于多线程通过共享内存进行通信时,存在的本地内存数据不一致、编译器会对代码指令重排序、处理器会对代码乱序执行等带来的问题。目的是保证并发编程场景中的原子性、可见性和有序性。

    Java内存模型的实现

    了解Java多线程的朋友都知道,在Java中提供了一系列和并发处理相关的关键字,比如volatile、synchronized、final、concurren包等。其实这些就是Java内存模型封装了底层的实现后提供给程序员使用的一些关键字。

    在开发多线程的代码的时候,我们可以直接使用synchronized等关键字来控制并发,从来就不需要关心底层的编译器优化、缓存一致性等问题。所以,Java内存模型,除了定义了一套规范,还提供了一系列原语,封装了底层实现后,供开发者直接使用。

    本文并不准备把所有的关键字逐一介绍其用法,因为关于各个关键字的用法,网上有很多资料。读者可以自行学习。本文还有一个重点要介绍的就是,我们前面提到,并发编程要解决原子性、有序性和一致性的问题,我们就再来看下,在Java中,分别使用什么方式来保证。

    原子性

    在Java中,为了保证原子性,提供了两个高级的字节码指令monitorenter和monitorexit。在synchronized的实现原理文章中,介绍过,这两个字节码,在Java中对应的关键字就是synchronized。

    因此,在Java中可以使用synchronized来保证方法和代码块内的操作是原子性的。

    可见性

    Java内存模型是通过在变量修改后将新值同步回主内存,在变量读取前从主内存刷新变量值的这种依赖主内存作为传递媒介的方式来实现的。

    Java中的volatile关键字提供了一个功能,那就是被其修饰的变量在被修改后可以立即同步到主内存,被其修饰的变量在每次是用之前都从主内存刷新。因此,可以使用volatile来保证多线程操作时变量的可见性。

    除了volatile,Java中的synchronized和final两个关键字也可以实现可见性。只不过实现方式不同,这里不再展开了。

    有序性

    在Java中,可以使用synchronized和volatile来保证多线程之间操作的有序性。实现方式有所区别:

    volatile关键字会禁止指令重排。synchronized关键字保证同一时刻只允许一条线程操作。

    好了,这里简单的介绍完了Java并发编程中解决原子性、可见性以及有序性可以使用的关键字。读者可能发现了,好像synchronized关键字是万能的,他可以同时满足以上三种特性,这其实也是很多人滥用synchronized的原因。

    但是synchronized是比较影响性能的,虽然编译器提供了很多锁优化技术,但是也不建议过度使用。

    总结

    在读完本文之后,相信你应该了解了什么是Java内存模型、Java内存模型的作用以及Java中内存模型做了什么事情等。

    关于Java中这些和内存模型有关的关键字,希望读者还可以继续深入学习,并且自己写几个例子亲自体会一下。可以参考《深入理解Java虚拟机》和《Java并发编程的艺术》两本书。

    展开全文
  • 在介绍Java内存模型之前,先来看一下到底什么是计算机内存模型,然后再来看Java内存模型在计算机内存模型的基础上做了哪些事情。要说计算机的内存模型,就要说一下一段古老的历史,看一下为什么要有内存模型。 内存...
  • 1.什么是计算机内存内存指的是内存储器 ,内存主要是用来临时存贮数据 ; EX:电脑中调用的数据,就需要从硬盘读出,发给内存,然后内存再发给CPU(也可以理解成是外存和CPU之间的缓存)。 在计算机的组成结构中,有一...
  • Java内存模型 Java内存模型的主要目标是定义程序中各个变量的访问规则,即在JVM中将变量存储到内存和从内存中取出变量这样的底层细节。此处的变量与Java编程里面的变量有所不同步,它包含了实例字段、静态字段和...
  • 定义 内存泄露(memory lock)是指由于疏忽或错误... 一般常说的内存泄露是指堆内存的泄露,堆是动态分配内存的,并且可以分配使用很大的内存,使用不好会产生内存泄露,使用不好会产生内存泄露。频繁的使用mallo...
  • 什么是Java内存模型

    千次阅读 2015-04-21 00:51:03
    概述:本文向您介绍Java内存模型的概念,在C或C++中, 利用不同操作平台下的内存模型来编写并发程序;Java利用了自身虚拟机的优势, 使内存模型不束缚于具体的处理器架构,真正实现了跨平台。  内存模型 ...
  • 什么是内存泄露?怎么检测

    千次阅读 2019-03-20 17:32:03
    什么是内存泄露? 简单地说就是申请了一块内存空间,使用完毕后没有释放掉。它的一般表现方式是程序运行时间越长,占用内存越多,最终用尽全部内存,整个系统崩溃。由程序申请的一块内存,且没有任何一个指针指向它...
  • 什么是内存墙”

    千次阅读 2010-12-27 20:35:00
    内存墙,指的是内存性能严重限制CPU性能发挥的现象。 在过去的20多年中,处理器的性能以每年大约55%速度快速提升,而内存性能的提升速度则只有每年10%左右。长期累积下来,不均衡的发展速度造成了当前内存的存取速度...
  • 内存的分类以及各自特征

    千次阅读 2020-03-11 21:04:05
    先说内存的含义: 内存是计算机中重要的部件之一,它是与CPU进行沟通的桥梁。计算机中所有程序的运行都是在内存中进行的,因此内存的性能对计算机的影响非常大。 内存(Memory)也被称为内存储器,其作用是用于暂时...
  • 工作笔试面试那些事儿(3)---内存管理那些事

    万次阅读 多人点赞 2013-08-30 22:56:46
    七、内存管理  在写C/C++程序的时候,最头疼的部分一定包括内存管理,一提到内存管理总是提心吊胆,但是又不可避免地常常会遇到,而这块的知识也是公司招聘的一个评价方面,能够很好地体现笔试面试者的功底。这部分...
  • 设定一个工作集窗口Δ和内存页面数M 用一个数据结构维护每个进程的工作集,这个数据结构可以是数组或链表 根据进程访问页面的顺序,动态更新每个进程的工作集合和内存的空闲页面数 内存页面不足时,暂停某些进程...
  • 堆和栈的区别 (stack and heap) 一般认为在c中分为这几个存储区 1栈 - 有编译器自动分配释放 2堆 - 一般由程序员分配释放,若程序员不释放,程序结束时可能由...什么变量在堆内存里存放,什么变量在栈内存里存放
  • ★ Java内存管理特点

    千次阅读 2007-09-30 15:31:00
    ★ Java内存管理特点 Java一个最大的优点就是取消了指针,由垃圾收集器来自动管理内存的回收。程序员不需要通过调用函数来释放内存。 1、Java的内存管理就是对象的分配和释放问题。 在Java中,程序员需要通过...
  • 凡是对电脑有所了解的朋友都知道内存这玩意,可是,可能有不少朋友对内存的认识仅仅局限在SDRAM和DDR SDRAM这两种类型,...以下就让我们看看内存到底有些什么种类吧! 一、RAM(Random Access Memory,随机存取存
  • 市面上有一些初学者的误解,他们拿spark和hadoop比较时就会说,Spark是内存计算,内存计算是spark的特性。...所有说sprk的特点内存计算相当于什么都没有说。那么spark的真正特点什么?抛开spark的执行模
  • 内存工作原理(一)

    千次阅读 2012-12-20 21:33:43
    现代的PC(包括NB)都是以存储器为核心的多总线结构,即CPU只通过存储总线与主存储器交换信息(先在Cache里找数据,如果找不到,再去主存找)。输入输出设备通过I/O总线直接与主存储器交换...内部存储器简称内存,也
  • 内存数据库

    千次阅读 2014-05-07 08:19:25
    内存数据库,顾名思义就是将数据放在内存中直接操作的数据库。相对于磁盘,内存的数据读写速度要高出几个数量级,将数据保存在内存中相比从磁盘上访问能够极大地提高应用的性能。同时,内存数据库抛弃了磁盘数据管理...
  • 原文链接:... .NET Core 配置GC工作模式与内存的影响 .NET Core GC 原文:https://blog.markvincze.com/troubleshooting-high-memory-usage-with-asp-net-core-on-kubernetes/ ...
  • 收集算法是内存回收的方法论,垃圾收集器是内存回收的具体实现。...但出现内存泄露和溢出问题时,如果不了解虚拟机是怎样使用内存的,那么排查错误将是一项非常艰难地工作。 GC(垃圾收集器)在对堆回收前,...
  • 对于JVM内存配置参数: -Xmx10240m -Xms10240m -Xmn5120m -XXSurvivorRatio=3 -Xms10240m 初始堆大小即最小内存值 XXSurvivorRatio=3,即Eden:FromSurvivor:ToSurvivor=3:1:1;所以Survivor一共是2048 -Xmx...
  • JVM:自动内存管理之Java内存区域与内存溢出

    千次阅读 多人点赞 2021-01-07 12:03:22
    本博客主要参考周志明老师的《深入理解Java...程序计数器是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器,在Java虚拟机的概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下.
  • 内存管理

    万次阅读 2015-03-12 17:09:40
    内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨,但内存管理在C++中无处不在,内存泄漏几乎在每个C++...
  • 因为内存已经成为每台电脑的必备配件,从EDO、SDRAM、DDR、DDR2再到现如今的DDR3内存,变化可谓是翻天覆地。内存无论是在容量、速度、性能上都有了显著的提高。    但是内存市场中,产品可谓是型号众多,比如...
  • 内存篇:JVM内存结构

    万次阅读 2019-11-01 19:50:24
    Java8相对之前的版本,JVM结构发生了较大的变化,取消了永久代,新增了元空间,同时,元空间不再与堆连续,而且是存在于本地内存(Native memory)。下面,以Java8为例,对JVM结构做一番总结。 JVM内存结构1 JVM结构...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 428,113
精华内容 171,245
关键字:

内存的工作特点是什么