精华内容
下载资源
问答
  • C++ 中内存对齐原理作用

    千次阅读 多人点赞 2018-01-07 16:54:46
    struct/class/union内存对齐原则有四个:1).数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小...

    struct/class/union内存对齐原则有四个:

    1).数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int在32位机为4字节, 则要从4的整数倍地址开始存储),基本类型不包括struct/class/uinon。

    2).结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部”最宽基本类型成员“的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)。

    3).收尾工作:结构体的总大小,也就是sizeof的结果,.必须是其内部最大成员的”最宽基本类型成员”的整数倍.不足的要补齐.(基本类型不包括struct/class/uinon)。

    4).sizeof(union),以结构里面size最大元素为union的size,因为在某一时刻,union只有一个成员真正存储于该地址。

    实例解释:下面以class为代表

    No.1

    class Data
    {
        char c;
        int a;
    };
    
    cout << sizeof(Data) << endl;

    No.2

    class Data
    {
        char c;
        double a;
    };
    
    cout << sizeof(Data) << endl;

    显然程序No.1 输出的结果为 8 No.2 输出的结果为 16 .

    No.1最大的数据成员是4bytes,1+4=5,补齐为4的倍数,也就是8。而No.2为8bytes,1+8=9,补齐为8的倍数,也就是16。

    No.3

    class Data
    {
        char c;
        int a;
        char d;
    };
    
    cout << sizeof(Data) << endl;

    No.4

    class Data
    {
        char c;
        char d;
        int a;
    };
    
    cout << sizeof(Data) << endl;

    No.3运行结果为 12 No.4运行结果为 8

    class中的数据成员放入内存的时候,内存拿出一个内存块来,数据成员们排队一个一个往里放,遇到太大的,不是把自己劈成两半,能放多少放多少,而是等下一个内存块过来。这样的话,就可以理解为什么No.3,No.4两端的代码输出结果不一样了,因为左边是1+(3)+4+1+(3)=12,而右边是1+1+(2)+4=8。括号中为补齐的bytes。

    No.5

    class BigData
    {
        char array[33];
    };
    
    class Data
    {
        BigData bd;
        int integer;
        double d;
    };
    
    cout << sizeof(BigData) << "   " << sizeof(Data) << endl;

    No.6

    class BigData
    {
        char array[33];
    };
    
    class Data
    {
        BigData bd;
        double d;
    };
    
    cout << sizeof(BigData) << "   " << sizeof(Data) << endl;

    No.5和No.6运行结果均为: 48

    在默认条件下,内存对齐是以class中最大的那个基本类型为基准的,如果class中有自定义类型,则递归的取其中最大的基本类型来参与比较。在No.5和No.6中内存块一个接一个的过来接走数据成员,一直到第5块的时候,BigData里只剩1个char了,将它放入内存块中,内存块还剩7个bytes,接下来是个int(4bytes),能够放下,所以也进入第5个内存块,这时候内存块还剩3bytes,而接下来是个double(8bytes),放不下,所以要等下一个内存快到来。因此,No.5的Data的size=33+4+(3)+8=48,同理No.6应该是33+(7)+8=48。

    顺便提一下Union: 共用体表示几个变量共用一个内存位置,在不同的时间保存不同的数据类型和不同长度的变量。在union中,所有的共用体成员共用一个空间,并且同一时间只能储存其中一个成员变量的值。

    No.7

    class A
    {
        int i;
        char c1;
    }
    
    class B:public A
    {
        char c2;
    }
    
    class C:public B
    {
        char c3;
    }

    sizeof(C)结果是多少呢,gcc和vs给出了不同的结果,分别是8、16

    gcc中:C相当于把所有成员i、c1、c2、c3当作是在一个class内部,(先继承后对齐)

    vs中:对于A,对齐后其大小是8;对于B,c2加上对齐后的A的大小是9,对齐后就是12;对于C,c3加上对齐后的B大小是13,再对齐就是16 (先对齐后继承)

    关于c++对象继承后的内存布局,更详细的分析可以《深度探索参考c++对象模型》第三章

    内存对齐的主要作用是:

    1、 平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

    2、 性能原因:经过内存对齐后,CPU的内存访问速度大大提升。具体原因稍后解释。

    这里写图片描述

    这是普通程序员心目中的内存印象,由一个个的字节组成,而CPU并不是这么看待的。

    这里写图片描述

    CPU把内存当成是一块一块的,块的大小可以是2,4,8,16字节大小,因此CPU在读取内存时是一块一块进行读取的。块大小成为memory access granularity(粒度) 本人把它翻译为“内存读取粒度” 。

    假设CPU要读取一个int型4字节大小的数据到寄存器中,分两种情况讨论:

    1、数据从0字节开始

    2、数据从1字节开始

    再次假设内存读取粒度为4。

    这里写图片描述

    当该数据是从0字节开始时,很CPU只需读取内存一次即可把这4字节的数据完全读取到寄存器中。

    当该数据是从1字节开始时,问题变的有些复杂,此时该int型数据不是位于内存读取边界上,这就是一类内存未对齐的数据。

    这里写图片描述

    此时CPU先访问一次内存,读取0—3字节的数据进寄存器,并再次读取4—5字节的数据进寄存器,接着把0字节和6,7,8字节的数据剔除,最后合并1,2,3,4字节的数据进寄存器。对一个内存未对齐的数据进行了这么多额外的操作,大大降低了CPU性能。

    这还属于乐观情况了,上文提到内存对齐的作用之一为平台的移植原因,因为以上操作只有有部分CPU肯干,其他一部分CPU遇到未对齐边界就直接罢工了。

    展开全文
  • 内存寻址原理

    万次阅读 2016-01-10 20:25:02
    今天绿盟科技的安全技术专家就讲讲这个内存寻址的原理,文章分为上下两篇《内存寻址原理》及《内存寻址方式》。 随着信息化发展和数据处理能力需求的提高,对计算机硬件产品的性能和容量也提出了新的挑战,要求...

    在做网络安全事件分析的时候,都会遇到内存寻址的知识,例如上次跟大家分享的《 空指针漏洞防护技术》,就涉及到非法访问内存地址的问题。如果这个坎儿迈不过去,你就会迷失在代码中,更无从分析了。今天绿盟科技的安全技术专家就讲讲这个内存寻址的原理,文章分为上下两篇《内存寻址原理》及《内存寻址方式》。

    随着信息化发展和数据处理能力需求的提高,对计算机硬件产品的性能和容量也提出了新的挑战,要求计算机处理能力也要能随实际情况需求的变动而提升、改变。

    当下,一台普通的电脑硬盘容量也要200多G,内存也有4G;如此大容量的硬盘和内存,在处理大量数据或是大型游戏面前还是显得力不从心,需要通过扩容来满足需求,比如将内存由4G提升到8G或是16G不等。扩容后对个人体验确实提升不少。对于内存容量的提升需要有相应的硬件基础支撑,需要有能消化掉这么多内存的寻址地址。比如说如果一8位单片机如果要装载16G的内存,那就是暴殄天物。

    哪里有需求哪里就有市场 ;计算机从8位的51单片机,20位8086寻址,发展到32位 win2003,64位win10,都是由于信息化需求的膨胀推动着计算机一代又一代的改革创新。

    对于内存的扩容,很多人都不是很清楚应用程序如何使用的物理内存地址。远了不说,单说现在常用计算机中的32位、64系统;系统是怎么样将虚拟地址转化成线性地址,线性地址又是怎样转换成物理地址的,其中又用到了哪些寄存器或是数据结构,相信很多人对此也是一知半解;也像我一样,想结合实例从地址转换的本质来掌握其精髓之处。接下来就一起学习从逻辑地址到物理地址的整个转换过程。

    1.实模式与保护模式简介

    CPU常见三种工作模式:实模式与保护模式,虚拟8086模式。

    实模式 :CPU复位(reset)或加电(power on)的时候以实模式启动,处理器以实模式工作。在实模式下,内存寻址方式和8086相同,由16位段寄存器的内容乘以16(10H)当做段基地址,加上16位偏移地址形成20位的物理地址,最大寻址空间1MB。在实模式下,所有的段都是可以读、写和可执行的。实模式下没有分段或是分页机制,逻辑地址和物理地址相等。

    由此得知:

    1. 在实模式下最大寻址空间时1M,1M以上的内存空间在实模式下不会被使用。
    2. 在实模式所有的内存数据都可以被访问。不存在用户态、内核态之分。
    3. 在BIOS加载、MBR、ntdlr启动阶段都处在实模式下。

    保护模式 :对于保护模式大家并不陌生;是目前操作系统的运行模式,利用内存管理机制来实现线性地址到物理地址的转换,具有完善的任务保护机制。

    保护模式常识:

    1. 现在应用程序运行的模式均处于保护模式。
    2. 横向保护,又叫任务间保护,多任务操作系统中,一个任务不能破坏另一个任务的代码,这是通过内存分页以及不同任务的内存页映射到不同物理内存上来实现的。
    3. 纵向保护,又叫任务内保护,系统代码与应用程序代码虽处于同一地址空间,但系统代码具有高优先级,应用程序代码处于低优先级,规定只能高优先级代码访问低优先级代码,这样杜绝用户代码破坏系统代码。

    虚拟8086 模式: 简称V86模式是运行在保护模式中的实模式,为了在32位保护模式下执行纯16位程序。可以把8086程序当做保护模式的一项任务来执行。虚拟8086允许在不退出保护模式的情况下执行8086程序。

    虚拟8086常识:

    1. 寻址的地址空间是1M字节.
    2. 可以在虚拟8086模式下运行16位DOS程序。
    3. 在V86模式下,代码段总是可写的;这与实模式相同,同理,数据段也是可执行的。
    4. 32系统编写V86模式的程序:

    2. 保护模式寻址基础知识

    接下来就以32位系统为例,介绍保护模式下,内存中一些地址转换相关的寄存机和数据结构。

    2.1 内存地址概念

    逻辑地址 :在进行C语言编程中,能读取变量地址值(&操作),实际上这个值就是逻辑地址,也可以是通过malloc或是new调用返回的地址。该地址是相对于当前进程数据段的地址,不和绝对物理地址相干。只有在Intel实模式下,逻辑地址才和物理地址相等(因为实模式没有分段或分页机制,CPU不进行自动地址转换)。应用程序员仅需和逻辑地址打交道,而分段和分页机制对一般程序员来说是完全透明的,仅由系统编程人员涉及。应用程序员虽然自己能直接操作内存,那也只能在操作系统给你分配的内存段操作。一个逻辑地址,是由一个段标识符加上一个指定段内相对地址的偏移量,表示为 [段标识符:段内偏移量]。

    线性地址 :是逻辑地址到物理地址变换之间的中间层。程序代码会产生逻辑地址,或说是段中的偏移地址,加上相应段的基地址就生成了一个线性地址。如果启用了分页机制,那么线性地址能再经变换以产生一个物理地址。若没有启用分页机制,那么线性地址直接就是物理地址。Intel 80386的线性地址空间容量为4G(2的32次方即32根地址总线寻址)。

    物理地址(Physical Address) 是指出目前CPU外部地址总线上的寻址物理内存的地址信号,是地址变换的最终结果地址。如果启用了分页机制,那么线性地址会使用页目录和页表中的项变换成物理地址。如果没有启用分页机制,那么线性地址就直接成为物理地址了,比如在实模式下。

    2.2 虚拟地址,线性地址,物理地址关系

    对于保护模式下地址之间的转换,对程序员来说是透明的。那么物理内存通过内存管理机制是如何将虚拟地址转换为物理地址的呢?

    1、当程序中的指令访问某一个逻辑地址时,CPU首先会根据段寄存器的内容将虚拟地址转化为线性地址。

    2、如果CPU发现包含该线性地址的内存页不在物理内存中就会产生缺页异常,该异常的处理程序通过是操作系统的内存管理器例程。内存管理器得到异常报告后会根据异常的状态信息。特别是CR2寄存器中包含的线性地址,将需要的内存页加载到物理内存中。

    3、然后异常处理程序返回使处理器重新执行导致页错误异常的指令,这时所需要的内存页已经在物理内存中,所以便不会再导致页错误异常。


    虚拟地址------(段机制)------->线性地址------(页机制)------->物理地址。


    注:Linux中虚拟地址和线性地址一般是一样的;Windows平坦内存模型中,虚拟地址和线性地址也一样。


    2.3 段式机制及实例分析

    前面说到在线性地址转换为物理地址之前,要先由逻辑地址转换为线性地址。系统采用段式管理机制来实现逻辑地址到线性地址的转换。保护模式下,通过”段选择符+段内偏移”寻址最终的线性地址。

    CPU的段机制提供一种手段可以将系统的内存空间划分为一个个较小的受保护的区域,每个区域为一个段。相对32位系统,也就是把4G的逻辑地址空间换分成不同的段。每个段都有自己的起始地址(基地址),边界和访问权限等属性。实现段机制的一个重要数据结构就是段描述符。

    下面是个程序实例中显示除了各个段的值:

    图中给出了代码段CS,堆栈段SS,数据段DS等段寄存器的值;从得到的值可知,SS=DS=ES是相等的,至于为什么有些段的值相等,后面会说到。 以实例中给出的地址0x83e84110 为例,哪里是段描述符,哪里是段内偏移, 又是如何将该逻辑地址转换为线性地址的呢?相信很多人都迫不及待的想知道整个转换过程,接下来就要看看逻辑地址到线性地址详细转换过程。

    上面说到段式管理模式下有段选择符+段内偏移寻址定位线性地址,其实际转换过程如下图所示

    从图中可知,逻辑地址到线性地址的转换,先是通过段选择符从描述符表中找到段描述符,把段描述符和偏移地址相加得到线性地址。也就是说要想得到段描述符需要三个条件:

    1. 得到段选择符。
    2. 得到段描述符表
    3. 从段描述符表中找到段描述符的索引定位段描述符。

    前面我们提到了段描述符 + 偏移地址,并没有提段选择符和段描述符表。所以我们要弄清楚这几个观念段选择符,段描述符表,段描述符,以及如何才能得到这几个描述符?

    2.3.1 段描述符基础知识

    从上图可知,通过段选择符要通过段描述符表找到段描述符,那么段描述符表是什么,又是怎么得到段描述符表呢?

    在保护模式下,每个内存段就是一个段描述符。其结构如下图所示:

    图中看出,一个段描述符是一个8字节长的数据结构,用来描述一个段的位置、大小、访问控制和状态等信息。段描述符最基本内容是段基址和边界。段基址以4字节表示(图中可看出3,4,5,8字节)。4字节刚好表示4G线性地址的任意地址(0×00000000-0xffffffff)。段边界20位表示(1,2字节及7字节的低四位)。

    2.3.2 段描述符表实例解析

    在现在多任务系统中,通常会同时存在多个任务,每个任务会有多个段,每个段需要一个段描述符,段描述符在上面一小节已经介绍,因此系统中会有很多段描述符。为了便于管理,需要将描述符保存于段描述符表中,也就是上图画出的段描述符表。IA-32处理器有3中描述符表:GDT,LDT和IDT。

    GDT是全局描述符表。一个系统通常只有一个GDT表。GDT表也即是上图中的段描述符表,供系统中所以程序和任务使用。至于LDT和IDT今天不是重点。

    那么如何找到GDT表的存放位置呢?系统中提供了GDTR寄存器用了表示GDT表的位置和边界,也就是系统是通过GDTR寄存器找到GDT表的;在32位模式下,其长度是48位,高32位是基地址,低16位是边界;在IA-32e模式下,长度是80位,高64位基地址,低16位边界。

    位于GDT表中的第一个表项(0号)的描述符保留不用,成为空描述符。如何查看系统的GDT表位置呢?通过查看GDTR寄存器,如下图所示

    从上图看出GDT表位置地址是0×8095000,gdtl值看出GDT边界1023,总长度1024字节。前面知道每一项段描述符占8字节。所以总共128个表项。图中第一表项是空描述符。

    2.3.3 段选择符结构

    前面我们介绍了段描述符表和段描述符的格式结构。那么如何通过段选择符找到段描述符呢,段选择符又是什么呢?

    段选择符又叫段选择子,是用来在段描述符表中定位需要的段描述符。段选择子格式如下:

    7

    段选择子占有16位两个字节,其中高13位是段描述在段描述表中的索引。低3位是一些其他的属性,这里不多介绍。使用13位地址,意味着最多可以索引8k=8192个描述符。但是我们知道了上节GDT最多128个表项。

    在保护模式下所有的段寄存器(CS,DS,ES,FS,GS)中存放的都是段选择子。

    2.3.4 逻辑地址到线性地址转换实例解析

    已经了解了逻辑地址到虚拟地址到线性地址的转换流程,那就看看在前面图中逻辑地址0x83e84110对应的线性地址是多少?

    首先,地址0x83e84110对应的是代码段的一个逻辑地址,地址偏移已经知道,也就是段内偏移知道,通过寄存器EIP得到是0x83e34110。段选择符是CS寄存器CS=0008,其高13位对应的GDT表的索引是1,也就是第二项段描述符(第一项是空描述符)。GDT表的第二项为标红的8个字节

    通过段描述的3,4,5,8个字节得到段基址。

    如上图所示第二项段描述符的3,4,5,8字节对应的值为0×00000000。由此我们得到了段机制和段内偏移。最后的线性地址为段基址+段内偏移=0×0+0x83e34110=0x83e34110。

    由此我们知道在32系统中逻辑地址就是线性地址。

    其实通过观察其他的段选择子会发现,所有段选择子对应的基地址都是0×0,这是因为在32系统保护模式下,使用了平坦内存模型,所用的基地址和边界值都一样。既然基地址都是0,那么也就是线性地址就等于段内偏移=逻辑地址。

    总之:

    1. 段描述符8字节
    2. GDTR是48位
    3. 段选择子2个字节。

    2.4 页式机制及实例分析

    前面介绍了由逻辑地址到线性地址的转换过程,那么接下来就要说说地址是如何将线性地址转为物理地址。需要先了解一些相关的数据结构。

    前面说到如果CPU发现包含该线性地址的内存页不在物理内存中就会产生缺页异常,该异常的处理程序通过是操作系统的内存管理器例程。内存管理器得到异常报告后会根据异常的状态信息。特别是CR2寄存器中包含的线性地址,将需要的内存页加载到物理内存中。然后异常处理处理返回使处理器重新执行导致页错误异常的指令,这时所需要的内存页已经在物理内存中,所以便不会再导致也错误异常。

    32位系统中通过页式管理机制实现线性地址到物理地址的转换,如下图:

    2.4.1 PDE结构及如何查找内存页目录

    从上图中我们知道通过寄存器CR3可以找到页目录表。那么CR3又是什么呢?在32系统中CR3存放的页目录的起始地址。CR3寄存器又称为页目录基址寄存器。32位系统中不同应用程序中4G线性地址对物理地址的映射不同,每个应用程序中CR3寄存器也不同。也就是说每个应用程序中页目录基址也是不同的。

    从上图知道页目录表用来存放页目录表项(PDE),页目录占一个4kb内存页,每个PDE长度为4字节,所以页目录最多包含1KB。没启用PAE时,有两种PDE,这里我们只讨论使用常见的指向4KB页表的PDE。

    页目录表项的高20位表示该PDE所指向的起始物理地址的高20位,该起始地址的低12位为0,也就是通过PDE高20位找到页表。由于页表低12位0,所以页表一定是4KB边界对齐。 也就是通过页目录表中的页目录表项来定位使用哪个页表(每一个应用程序有很多页表)。

    以启动的calc程序为例,CR3寄存器是DirBase中的值,如下图

    Calc.exe程序对应的CR3寄存器值为0x2960a000,下面是对应PDT结构

    2.4.2页表结构解析

    页表是用来存放页表表项(PTE)。每一个页表占4KB的内存页,每个PTE占4个字节。所以每个页表最多1024个PTE。其中高20位代表要使用的最终页面的起始物理地址的高20位。所以4KB的内存页也都是4KB边界对齐。



    from: http://blog.jobbole.com/90947/

    展开全文
  • ESXi 内存分配原理

    千次阅读 2019-11-05 10:28:02
    上一篇我们详细讲述了CPU的调度原理,本篇讲一下内存的分配过程。 运行在ESXi主机上的虚拟机分配内存之和可以超过物理机的实际内存大小,这个技术叫做超额分配(overcommitment),即使单个虚拟机的内存分配值都...

    上一篇我们详细讲述了CPU的调度原理,本篇讲一下内存的分配过程。

     

    运行在ESXi主机上的虚拟机分配内存之和可以超过物理机的实际内存大小,这个技术叫做超额分配(overcommitment),即使单个虚拟机的内存分配值都可以超分。但是超分的结果就是可能会引起内存资源竞争,从而有可能影响到性能。

     

    VMkernel中有另外一个组件叫做memory allocator,用来负责内存资源的分配,(负责CPU调度的是scheduler,上一篇提到过),如下图:

     

     

    那么内存分配的过程究竟是怎样的呢?我们来详细描述一下:

     

    • 首先,内存分为三个级别,主机物理内存,客户机物理内存(虚拟机分配的内存大小),客户机虚拟内存(应用程序使用的内存)。虚拟机开机后,VMkernel 不会立即分配所有的客户机物理内存给虚拟机,初始阶段是根据OS和应用程序的需要按需分配,如下图所示。这个时候,VMkernel会把物理机的内存页面地址映射给客户机物理内存页面,从而实现内存虚拟化。

     

     

    • 其次,当OS和应用程序释放内存的时候,Guest OS会把这些内存页面地址放在free list,但是VMkernel并不知道这个list,也就是说,VMkernel是不知道Guest里边有内存释放,也不会知道哪些应用程序正在占用哪些内存页面,它只知道虚拟机分配的内存大小。(是不是感觉VMkernel挺傻的,自己的东西分给别人了,但是别人用不用也不知道,直到最后自己的东西被分完了。)如下图所示:

     

     

    其中,free list是Guest OS没有分配给应用程序的,左侧第一个“红色”内存页面是应用程序暂时不用的,被称为“Idle--闲置”内存,其他三个内存页面(黄色,蓝色,灰色)是应用程序正在使用的,被称为“Active--活动”内存,所以Guest OS会把内存分为下图的树形结构:

     

     

    • 最后,当内存超分时,虚拟机请求的内存达到或者超过实际的物理内存大小时,VMkernel就要对分配出去的内存进行回收,从而触发四种内存回收机制,目的是为了保证所有的虚拟机都可以共享到内存资源,默认情况下,物理内存是平均分配的,但是如果管理员设置了资源控制参数(预留,限制,份额),那么VMkernel就会按照优先级对虚拟机的内存请求进行重分配。

       

    关于超分情况下,在内存竞争时,VMkernel如何进行内存回收呢?且听下回分解~

    展开全文
  • 计算机内存原理

    2018-06-22 20:36:23
    感觉内存不够用!!感觉电脑不够快!!

    前言——    

        内存是一盘与CUP的桥梁,其作用不言而喻,但是大多数人都是关注内存的大小而忽略了内存还有读写速度、带宽差距。

    正文——   

        一般我们将内存分为:堆区、栈区、全局区、代码区、常量区,各个区域存放的内容:

    栈区:在程序中所创建的局部变量、参数、数组、指针等,当程序执行完后,将释放所占用的该块内存。

    堆区:该片区域中存放着我们手工申请的内容,如:Malloc、new所创建。

    全局区:全局变量、静态变量,在我们程序执行完之后将自动释放所占用的内存。

    代码区:存放着函数体的二进制代码。

    常量区:包含着整形常量、字符串常量,该区域内容不能被修改。


     

        可以通过计算机虚拟内存解决一般内存不够用的情况


    展开全文
  • Java耗内存原理

    千次阅读 2017-10-28 19:55:12
    Java程序在内存中的分配为堆内存和栈内存,了解了堆内存和栈内存原理就能看出Java程序比较耗内存的原因了。
  • 内存工作原理

    千次阅读 2015-11-29 14:18:51
    现代的PC(包括NB)都是以存储器为核心的多总线结构,即CPU只通过存储总线与主存储器交换信息(先在Cache里找数据,如果找不到,再去主存找)。输入输出设备通过I/O总线直接与主存储器...内部存储器简称内存,也可称
  • JVM 堆内存设置原理

    万次阅读 多人点赞 2013-12-05 12:41:25
    原理 JVM堆内存分为2块:Permanent Space 和 Heap Space。 Permanent 即 持久代(Permanent Generation),主要存放的是Java类定义信息,与垃圾收集器要收集的Java对象关系不大。Heap = { Old + NEW = {Eden...
  • ThreadLocal起到了什么作用?ThreadLocal的应用场景在哪里? 举个例子:  在一个web应用中,我们常常用到了数据库连接池(本质就是线程池),一般的业务流程是从controller 到 service 到 dao,而service和dao中就...
  • 深入学习JVM内存设置原理和调优

    千次阅读 2016-06-03 16:41:50
    你知道JVM内存设置原理吗,这里和大家分享一下,因为如果默认的java虚拟机的大小比较小,在对大数据进行处理时java就会报错:java.lang.OutOfMemoryError。 这里向大家描述一下JVM内存设置原理内存调优...
  • Netty内存原理分析

    万次阅读 2015-04-29 22:13:08
    为了避免频繁的内存分配给系统带来负担以及GC对系统性能带来波动,Netty4提出了全新的内存管理,使用了全新的内存池来管理内存的分配和回收。内存池这块的代码晦涩难懂,而且几乎没有注释,所以阅读起来比较费力,...
  • Java内存区域划分、内存分配原理

    万次阅读 多人点赞 2014-11-16 16:20:30
    总结自《深入理解Java虚拟机》之内存区域划分。
  • 前言:JMM基础-计算机原理 1、物理内存模型带来的问题 2、伪共享 3、Java内存模型(JMM) 4、Java内存模型带来的问题 4.1 可见性问题 4.2 竞争问题 4.3 重排序 5、volatile详解 5.1 volatile特性 5.2 ...
  • Android内存管理原理

    千次阅读 2014-06-08 23:15:11
    一般来说,程序使用内存的方式遵循先向操作系统申请一块内存,使用内存,使用完毕之后释放内存归还给操作系统。然而在传统的C/C++等要求显式释放内存的编程语言中,记得在合适的时候释放内存是一个很有难度的工作,...
  • 内存屏障底层原理

    千次阅读 2017-11-06 14:09:08
    内存屏障是一个很晦涩的概念,今天为了让大家彻底了解在高级并发里面的这个高级主题,我们从系统层面向大家讲解内存屏障的原理、种类、应用, 下面的内容可能牵涉的东西比较多并且比较长,但是如果你耐心的看完,...
  • Java核心-内存分配原理详解

    千次阅读 2013-11-22 17:54:59
    无意中看到的一篇不错的文章,转载记录一下,Java核心-内存分配原理详解 概述 栈、堆、常量池虽同属java内存分配时操作的区域,但其适应范围和功用却大不相同。java内存分配与管理是java的核心技术之一,一般...
  • 随着持久内存逐步走向商用,DAX这个概念的出现频率日益增加。那么DAX究竟起到什么作用,其背后的原理又是什么?本文将率先对其进行揭晓。
  • android 内存基本原理和机制管理

    千次阅读 2016-05-13 11:03:37
    2,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的。 3,Java语言没有提供释放已分配内存的显示操作方法。垃圾回收原理垃圾回收器通常是作为一个单独的低级别的线程运行
  • 一、闭包的实现原理作用,可以列举几个开发中闭包的实际应用 1、闭包的概念:指有权访问另一个函数作用域中的变量的函数,一般情况就是在一个函数中包含另一个函数。 2、闭包的作用:访问函数内部变量、保持函数在...
  • C#内存释放 原理

    千次阅读 2013-08-25 15:13:42
    很多人对此不是很了解,其 实.Net所指的托管只是针对内存这一个方面,并不是对于所有的资源;因此对于Stream,数据库的连接,GDI+的相关对象,还有Com对象等等,这 些资源并不是受到.Net管理而统称为非托管资源。
  • 32位cpu为例,cpu在访问内存的时候是以一个字进行传输的(计算机中,一个机器字长就是cpu位数,32位cpu,四个字节为一个字),那么也就是说cpu读取数据每次都是四个字节四个字节的读取,计算机最初是从地址0开始寻址...
  • Memcache内存分配原理介绍

    千次阅读 2015-06-15 14:23:06
    它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并
  • 文章目录目录前文列表大页内存Linux 的大页内存大页的实现原理大页内存配置透明巨型页 THP大页面对内存的影响大页内存的性能问题 前文列表 大页内存 在页式虚拟存储器中,会在虚拟存储空间和物理主存空间都分割为一...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 368,038
精华内容 147,215
关键字:

内存的作用原理