内存对齐

Go的内存对齐

落爺英雄遲暮 提交于 2020-04-04 16:48:31
从煎鱼那看的,也是扫盲系列,细节具体等慢慢补充,先开题感受下。 这就是没内存对齐,这就导致了我们取1-4花了两步。实际上我们很多都是默认开内存对齐的,那么还有什么研究的,可以稍微优化一些,比如下面这种。 type Part1 struct { a bool b int32 c int8 d int64 e byte } type Part2 struct { c int8 a bool e byte b int32 d int64 } func main() { part1 := Part1{} part2 := Part2{} fmt.Println(unsafe.Sizeof(part1), unsafe.Alignof(part1)) fmt.Println(unsafe.Sizeof(part2), unsafe.Alignof(part2)) } 输出 32 8 16 8 Part1 axxx|bbbb|cxxx|xxxx|dddd|dddd|exxx|xxxx Part2 ecax|bbbb|dddd|dddd https://eddycjy.gitbook.io/golang/di-1-ke-za-tan/go-memory-align 来源: https://www.cnblogs.com/CherryTab/p/12632032.html

Ehcache计算Java对象内存大小

最后都变了- 提交于 2020-03-24 06:25:00
在EHCache中,可以设置maxBytesLocalHeap、maxBytesLocalOffHeap、maxBytesLocalDisk值,以控制Cache占用的内存、磁盘的大小(注:这里Off Heap是指Element中的值已被序列化,但是还没写入磁盘的状态,貌似只有企业版的EHCache支持这种配置;而这里maxBytesLocalDisk是指在最大在磁盘中的数据大小,而不是磁盘文件大小,因为磁盘文中有一些数据是空闲区),因而EHCache需要有一种机制计算一个类在内存、磁盘中占用的字节数,其中在磁盘中占用的字节大小计算比较容易,只需要知道序列化后字节数组的大小,并且加上一些统计信息,如过期时间、磁盘位置、命中次数等信息即可,而要计算一个对象实例在内存中占用的大小则要复杂一些。 计算一个实例内存占用大小思路 在Java中,除了基本类型,其他所有通过字段包含其他实例的关系都是引用关系,因而我们不能直接计算该实例占用的内存大小,而是要递归的计算其所有字段占用的内存大小的和。在Java中,我们可以将所有这些通过字段引用简单的看成一种树状结构,这样就可以遍历这棵树,计算每个节点占用的内存大小,所有这些节点占用的内存大小的总和就当前实例占用的内存大小,遍历的算法有:先序遍历、中序遍历、后序遍历、层级遍历等。但是在实际情况中很容易出现环状引用(最简单的是两个实例之间的直接引用

VC++中内存对齐

不想你离开。 提交于 2020-03-24 03:01:27
我们经常看到求 sizeof(A) 的值的问题,其中A是一个结构体,类,或者联合体。 为了优化CPU访问和优化内存,减少内存碎片,编译器对内存对齐制定了一些规则。但是,不同的编译器可能有不同的实现,本文只针对VC++编译器,这里使用的IDE是VS2012。 #pragma pack()是一个预处理,表示内存对齐。布局控制#pragma,为编译程序提供非常规的控制流信息。 /**********结构体的大小的规则*************/ 结构体大小是处理器位数和结构体内最长数据元素所占字节数二者中较小的那一个的整数倍。 比如说,假设处理器位数为n,结构体内最大数据元素所占字节数为m。 处理器为32位,n = 4;结构体内最大数据类型为short,m = 2; n > m;结构体大小为m的整数倍,反之亦然。 注意:有些虽然是64位的操作系统,但是编译器却是32位的,此时位数为32. 1 class A{ 2   int a; 3   char b; 4   short c; 5 }; sizeof(A)为8,为4的整数倍。 1 struct B{ 2 short a; 3 short b; 4 short c; 5 }; sizeof(B)为6,为2(sizeof(short))的整数倍。 注意:C++中的结构体与类只有一个区别,就是结构体成员默认是public

sizeof()与内存对齐问题小探讨

强颜欢笑 提交于 2020-03-18 05:08:25
关于sizeof输出问题 看下面一个例子: int main() {   char *ss1 = "0123456789";   char ss2[] = "0123456789";    char ss3[100] = "0123456789";   //内存对齐问题   struct { int a; char b; int c; char d; }st1;   struct { int a[10]; char b; char c; }st2;   printf("length1: %d;length2: %d; length3: %d, length4: %d, length5: %d\n",sizeof(ss1),sizeof(ss2), \   sizeof(ss3), sizeof(st1),sizeof(st2));   return 0; } 结果为4,11,100,16,48. 因为ss1首先是一个指针变量,它指向一个字符串,而sizeof输出的是给它传递的变量的长度,因此结果是4; 而对ss2来说,它是一个数组,它的长度未定义,因此要根据字符串的长度来算,再加上一个结束'\0',因此是11; 对于ss3它是一个有固定长度100的字符串,因此输出100; 对于结构体变量st1,与st2来说,默认情况下,为了便于对结构体内元素的访问与管理

内存对齐详细解释

天涯浪子 提交于 2020-03-03 21:02:01
内存对齐详细解释 如果 结构体存储下标从0 開始的 先是依照#pragma pack(8)參数依次和数据成员比較:依照 成员下标是比較结果中小者的倍数 ; 最后再依照#pragma pack(8)參数与结构体成员占空间最大者比較, 结构体总体的长度是比較结果中小者的倍数; 1、分析说明: 字节对齐(#pragma pack(2)) 输出结果:sizeof(structtest_t) = 10 [两个编译器输出一致] 分析过程: 1) 成员数据对齐 #pragmapack(2) structtest_t { inta; /* 长度4> 2 按2 对齐; 起始 offset=0 0%2=0;存放位置区间[0,3]*/ charb; /* 长度1< 2 按1 对齐; 起始 offset=4 4%1=0;存放位置区间[4]*/ shortc; /* 长度2= 2 按2 对齐; 起始 offset=6 6%2=0。存放位置区间[6,7]*/ chard; /* 长度1< 2 按1 对齐; 起始 offset=8 8%1=0;存放位置区间[8]*/ }; #pragmapack() 成员总大小 =9 2) 总体对齐 总体对齐系数=min((max(int,short,char), 2) = 2 总体大小 (size)=$( 成员总大小 ) 按 $( 总体对齐系数 ) 圆整 = 10 /* 10

内存对齐(转载)

依然范特西╮ 提交于 2020-03-03 19:10:56
目录 内存对齐指令 内存对齐的三条规则 另外还有两个需要注意的点: 下面开始举栗子说明 字节对齐的原因: C/C++中内存对齐问题的一些理解,转载于zhihu 内存管理是C/C++编程非常重要的一部分内容,熟悉C/C++中一些常见数据结构和数据类型的内存分布情况,可以很大程度上降低了coding过程中内存泄漏和越界等比较严重的内存问题,下面主要讨论一下结构体(类中同样存在内存对齐,内存对齐会复杂一些,涉及到虚表等问题,后面介绍类的时候会提到)中的内存对齐问题。 如有侵权,请联系删除,如有错误,欢迎大家指正,谢谢 内存对齐指令 一般来说,内存对齐过程对coding者来说是透明的,是由编译器控制完成的 如对内存对齐有明确要求,可用#pragma pack(n)指定,以n和结构体中最长数据成员长度中较小者为有效值 如未明确指定时,以结构体中最长的数据成员长度作为内存对齐的有效值 以下如没有特殊说明,均视为情况3(未明确指定)计算 内存对齐的三条规则 数据成员对齐规则,结构体(struct)(或联合(union))的数据成员,第一个数据成员存放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员(只要该成员有子成员,比如数组、结构体等)大小的整数倍开始(如:int 在 64bit 目标平台下占用 4Byte,则要从4的整数倍地址开始存储) 结构体作为成员

对于流程优化的处理器架构

佐手、 提交于 2020-03-02 15:40:46
在过去的两年里,我学到了很多的代码优化方法的同事,在此汇总了什么。 优化处理器架构可以从下面几个方向展开:高速缓存命中。指令预测。数据预取,数据对齐,内存拷贝优化,ddr访问延迟。硬件内存管理优化,指令优化。叙述工具。 缓存未命中是处理器的主要性能瓶颈之中的一个。在FSL的powerpc上,訪问一级缓存是3个时钟周期,二级是12个,3级30多个。内存100个以上。一级缓存和内存訪问速度差30多倍。 我们能够算一下,假设仅仅有一级缓存和内存,100条存取指令。100%命中和95%命中。前者300周期,后者95*3+5*100=785周期,差了1.6倍。这个结果的前提是powerpc上每一个核心仅仅有1个存取单元,使得多发射也无法让存取指令更快完毕。 当然,假设未命中的指令分布的好,其中穿插了非常多别的非存取指令那就能够利用乱序多做些事情,提高效率。 怎么用代码提高缓存命中率?我们能够用指令预測和数据预取。 指令预測非经常见,处理器预測将要运行的一个分支,把兴许指令取出来先运行。 等真正确定推断条件的时候,假设预測对了,提交结果。假设不正确,丢掉预先运行的结果。又一次抓取指令。 此时,结果还是正确的,可是性能会损失。 有一个经常使用的指令预測机制叫btb(branch target buffer),大致方法是,对于跳转指令,把它近期几次的跳转结果记录下来

剖析含有静态成员变量类的内存分布

依然范特西╮ 提交于 2020-03-01 15:39:21
如题所诉,对于含有静态成员变量的类其内存分布应该怎样呢?首先,我们知道静态成员变量任何对象都可以访问,但是它只存在一份,被所以对象共享。但是不属于对象本身,它在对象外构造。举例如下: #include <iostream> using namespace std; class Point3d { public: virtual ~Point3d(){} void print() { printf("&Point3d::x = %p\n", &Point3d::x);//打印在类Point3d中成员x的偏移值。 printf("&Point3d::y = %p\n", &Point3d::y);//打印在类Point3d中成员x的偏移值。 printf("&Point3d::z = %p\n", &Point3d::z);//打印在类Point3d中成员x的偏移值。 } protected: static Point3d origin; float x, y, z; }; int main() { Point3d s; s.print(); cout << sizeof(s) << endl;//打印对象的大小。 return 0; } 大家分析一下就知道,结果是:&Point3d::x = 00000008 &Point3d::y = 0000000c &Point3d::z =

20180315 代码错题(2)

末鹿安然 提交于 2020-02-28 00:56:11
下面两个结构体 1 2 3 4 5 6 7 8 9 10 struct One{ double d; char c; int i; } struct Two{ char c; double d; int i; } 在#pragma pack(4)和#pragma pack(8)的情况下,结构体的大小分别是 16 24,16 24 16 20,16 20 16 16,16 24 16 16,24 24答案C 错选D 许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数,这就是所谓的内存对齐。 每个特定平台上的编译器都有自己的默认“对齐系数”(32位机一般为4,64位机一般为8)。我们可以通过预编译命令#pragma pack(k),k=1,2,4,8,16来改变这个系数,其中k就是需要指定的“对齐系数”;也可以使用#pragma pack()取消自定义字节对齐方式。 struct 或者 union 成员对齐规则如下: 1. 第一个数据成员放在offset为0的地方,对齐按照对齐系数和自身占用字节数中,二者比较小的那个进行对齐; 2. 在数据成员完成各自对齐以后,struct或者union本身也要进行对齐,对齐将按照对齐系数和struct或者union中最大数据成员长度中比较小的那个进行; 先局部成员对齐

内存对齐

只愿长相守 提交于 2020-02-26 20:03:32
在结构体中,首次接触到了内存对齐 typedef struct inf { char name ; int age ; char sex ; } inf ; int main ( ) { inf zhang ; printf ( "sizefof = %d\n" , sizeof ( zhang ) ) ; return 0 ; } 结果: [ jwq@localhost memory ] $ . / mem_alg sizefof = 12 为什么要内存对齐? 计算机的内存是以字节(Byte)为单位划分的,理论上cpu可以访问任意编号的字节,但实际上不是如此。 以32位cpu为例,一次可以处理32位的数据,因此命令地址总线每次读取4字节的数据(32位)。这样能最有效的处理数据,因此 cpu寻址 以4字节为一个 步长 ,这样可以最快的速度寻址并处理数据,同时又不会造成遗漏。 对与程序来说一个变量最好位于一个寻址步长之内。若果不是那么需要分次读取再拼接数据,这样效率变低。 **将一个数据尽量放在一个步长之内,避免跨步长存储,这称为内存对齐。**这是一种牺牲空间换时间的做法。 最后,内存对齐的大小可以自己设定。 来源: CSDN 作者: 和平精英总指挥 链接: https://blog.csdn.net/weixin_44997886/article/details/104519485