为什么 64 位程序执行同样的代码,比 32 位程序占用的内存要多(自己测试将近一半)?

2020-12-03 10:12:06 +08:00
 youla
//测试用到的代码

Task.Factory.StartNew(() =>{
	for (int i = 0; i < 999999; i++){
		int len = 255;
		IntPtr ptr = Marshal.AllocHGlobal(len);
		QueryFullProcessImageName(-1, 0, ptr, ref len);
		Console.WriteLine(Marshal.PtrToStringUni(ptr));
		Marshal.FreeHGlobal(ptr);
	}
});

门外汉

坐等摸鱼大佬

4427 次点击
所在节点    程序员
22 条回复
longaiwp
2020-12-03 10:16:57 +08:00
这难道不是意料之中的事情吗?你的问题是为什么会增加还是为什么会增加一半?
0x2CA
2020-12-03 10:20:36 +08:00
32 位编译器:

char:1 个字节
char*(即指针变量): 4 个字节( 32 位的寻址空间是 2^32, 即 32 个 bit,也就是 4 个字节。同理 64 位编译器)
short int : 2 个字节
int: 4 个字节
unsigned int : 4 个字节
float: 4 个字节
double: 8 个字节
long: 4 个字节
long long: 8 个字节
unsigned long: 4 个字节

64 位编译器:

char:1 个字节
char*(即指针变量): 8 个字节
short int : 2 个字节
int: 4 个字节
unsigned int : 4 个字节
float: 4 个字节
double: 8 个字节
long: 8 个字节
long long: 8 个字节
unsigned long: 8 个字节
shawndev
2020-12-03 10:23:51 +08:00
相同的数据类型会占用更多的内存空间
Jooooooooo
2020-12-03 10:26:54 +08:00
你原来用 北京市-朝阳区 定位人

现在用 中国-北京市-朝阳区-望京 定位人

写出来占空间更大了吧
youla
2020-12-03 10:35:43 +08:00
如果可以还想问一下,上面的代码写的有问题没??和下面这样写哪个好点???

int len = 255;
char[] data=new char[len];
QueryFullProcessImageName(-1, 0, data, ref len);
Console.WriteLine(new string(data,0,data.Length).TrimEnd('\0'));
codehz
2020-12-03 10:45:47 +08:00
显然指针的大小的变化不至于导致 heap alloc 的大小同比例增加,这里的原因是 x64 本身运行时环境自带的 overhead,不过不用担心,很大一部分都是由于调试需要才造成的,release 版本不会相差很多
jasonkayzk
2020-12-03 10:49:49 +08:00
x86 和 x64 的指针大小都是不一样的;
NNS71L068O2v70DB
2020-12-03 11:09:01 +08:00
指针大小不一致,基础数据类型比如 int 在两个平台上大小不一致,另外我比较好奇,如果是像 go 那种,全部是什么 int32 这种的话。大小会是什么变化
ysc3839
2020-12-03 12:37:55 +08:00
@youla C# 我不熟悉,但是 C++ 的话是会避免自己 new 之后再拷贝的,比如要把结果保存到 std::string 中的话,会直接 string.resize() 分配空间,然后用 string.data() 获取数据指针,然后直接写进去。
lxilu
2020-12-03 12:45:01 +08:00
直接 String/Builder 就行
@0x2CA 看清楚啊,这是 C#,简单类型尺寸固定,指针随平台。
f6x
2020-12-03 12:46:36 +08:00
硬盘++, 内存+
耗时-

你选吧.
Jasmine2016
2020-12-03 14:03:55 +08:00
这要从计算机原理说起。。
qinyusen
2020-12-03 14:20:13 +08:00
去年给校招出的题目就是考察这个的。。。供参考
填空题和简答题
1.对于 32 位系统 sizeof(int) 的值等于`__________`

5 在一个 64 位或 32 操作系统中以下代码输出的结果是(多选)?
```
std::cout<<sizeof(NULL)<<sizeof("NULL")<<std::endl;
```
A 88
B 85
C 44
D 45

7. 写出运行结果:

// test1
char str[] = "world";
cout << sizeof(str) << ": ";
char *p = str;
cout << sizeof(p) << ": ";
char i = 10;
cout << sizeof(i) << ": ";
void *pp = malloc(10);
cout << sizeof(pp) << endl;

`__________`
dream4ever
2020-12-03 14:31:26 +08:00
别的不说,这增加的是一倍吧?不是一半吧? 10 * 200% = 20,而不是 10 * 150% = 20
ragnaroks
2020-12-03 14:41:10 +08:00
这个测试不妥当,我有个 dotnet core 的控制台应用程序,32 位下 17M 内存,64 位下 21M,个人理解也就指针占用多了点,其它应该完全相同
nuk
2020-12-03 14:49:02 +08:00
没看出来这样测试有啥意义,都没分配多少内存,差的就是运行时用的内存吧,起码 GC 里保存的都是 64 位的地址?
ysc3839
2020-12-03 15:09:05 +08:00
@qinyusen 这第五题有问题吧? NULL 具体实现是看编译器的,有的编译器就只是一个 0,此时类型是 int,长度为 4 。
dadachen1997
2020-12-03 15:14:16 +08:00
因为指针的长度 double 了,在现代的语言里面,每个 object 的 header 包含的指针太多了,基本上 32 到 64 空间占用会多 80%
XDy0
2020-12-03 15:22:37 +08:00
经典面试题。。指针压缩。。。
qinyusen
2020-12-03 16:10:49 +08:00
@ysc3839 对,但是选择题,不是填空,所以,只要知道说的是啥就行

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/731632

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX