从我迄今为止发现的情况来看,很明显,针对64位体系结构编译的程序使用的指针的内存是其32位替代方法的两倍 – https://superuser.com/questions/56540/32-bit-vs- 64位系统 。 这是否意味着为64位编译的代码平均使用比32位版本多两倍的内存 ? 我怀疑它,但我想知道真正的开销是什么。 我想在64位体系结构中,像short , byte和char这样的小types是相同的? 虽然我不太确定byte 。 鉴于许多应用程序都使用大型string(如Web浏览器等),大多数实现中都由char数组组成,所以开销可能不会那么大。 所以,即使像int和long这样的数字types在64位上更大,是否会对RAM的使用有重要影响?
我知道将dynamic分配数组的长度传递给操作它们的函数是一个常见的约定: void initializeAndFree(int* anArray, size_t length); int main(){ size_t arrayLength = 0; scanf("%d", &arrayLength); int* myArray = (int*)malloc(sizeof(int)*arrayLength); initializeAndFree(myArray, arrayLength); } void initializeAndFree(int* anArray, size_t length){ int i = 0; for (i = 0; i < length; i++) { anArray[i] = 0; } free(anArray); } 但是如果没有办法让我从指针中获取分配的内存的长度,那么free()自动“知道当我给它的东西是什么时候释放的是同一个指针? 为什么我不能像C程序员那样获得魔法? free()从哪里获得免费(har-har)知识?
编译器书(龙书)解释了在堆栈上创build值types,并在堆上创build引用types。 对于Java,JVM还包含运行时数据区域中的堆栈和堆栈。 对象和数组在堆上创build,方法框架被推入堆栈。 一个堆被所有线程共享,而每个线程都有自己的堆栈。 下图显示了这一点: 关于Java运行时数据区域的更多信息 我不明白的是,由于JVM本质上是一个软件,那么这些JVM堆,堆栈和线程如何映射到物理机器呢? 如果有人能比较Java和C ++之间的概念,我将不胜感激。 因为Java在JVM上运行,但是C ++没有。 为了使这个问题更加精确,我想知道以下几点: 与Java相比,C ++运行时数据区是什么样的? 一张照片会很有帮助,我找不到像上面的JVM那样的好照片。 JVM堆,堆栈,寄存器和线程如何映射到操作系统? 或者我应该问他们如何映射到物理机器? 每个JVM线程是否仅仅是一个用户线程,并以某种方式映射到内核? (用户线程vs内核线程) 更新 :我画一个进程的运行时物理内存的图片。
tcmalloc / jemalloc是改进的内存分配器,内存池也被引入更好的内存分配。 那么它们之间有什么区别,以及如何在我的应用程序中select它们呢?
有人可以解释跳转表的机制,为什么在embedded式系统中需要?
我有点困惑使用StringBuilder类,第一: string对象连接操作总是从现有string和新数据创build一个新对象。 一个StringBuilder对象维护一个缓冲区以适应新数据的连接。 如果空间可用,新的数据被附加到缓冲区的末尾; 否则,分配一个新的,更大的缓冲区,将来自原始缓冲区的数据复制到新的缓冲区,然后将新的数据附加到新的缓冲区。 但是,创buildStringBuilder实例的目的是为了避免创build一个新的String ? 这听起来像交易“一对一”。 static void Main(string[] args) { String foo = "123"; using (StringBuilder sb = new StringBuilder(foo)) // also sb isn't disposable, so there will be error { sb.Append("456"); foo = sb.ToString(); } Console.WriteLine(foo); Console.ReadKey(); } 为什么我不应该只使用 += 编辑:好吧,我现在知道如何重用StringBuilder一个实例(仍然不知道这是否正确与代码标准),但这是不值得用一个string ,不是吗?
[编辑:这个问题只适用于32位系统。 如果你的计算机,你的操作系统和你的python实现是64位的,那么mmap-large文件的工作是可靠的,效率非常高。 我正在写一个模块,其中包括允许按位读取访问文件。 这些文件可能很大(数百GB),所以我写了一个简单的类,让我像string一样对待文件,并隐藏所有的查找和读取。 当时我写封装类,我不知道mmap模块 。 在阅读mmap的文档时,我认为“很好 – 这正是我所需要的,我将取出我的代码,并用mmapreplace它,这可能更有效,删除代码总是好的。 问题是,mmap不适用于大文件! 这对我来说是非常惊人的,因为我认为这也许是最明显的应用。 如果该文件高于几千兆字节,那么我得到一个EnvironmentError: [Errno 12] Cannot allocate memory 。 这只会发生在一个32位的Python版本,所以它似乎没有地址空间,但我找不到任何文档。 我的代码只是 f = open('somelargefile', 'rb') map = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) 所以我的问题是我在这里错过了一些明显的东西? 有没有办法让mmap在大文件上移植工作,还是应该回到我的天真文件包装? 更新:似乎有一种感觉,Python mmap应该与POSIX mmap具有相同的限制。 为了更好地expression我的挫折感,这里有一个简单的类,它只有mmap的一小部分function。 import os class Mmap(object): def __init__(self, f): """Initialise with a file object.""" self.source = f def __getitem__(self, key): try: # […]
我试图在L1caching中获得全部带宽,以便在Intel处理器上使用以下function float triad(float *x, float *y, float *z, const int n) { float k = 3.14159f; for(int i=0; i<n; i++) { z[i] = x[i] + k*y[i]; } } 这是STREAM的三合一function。 使用此function的SandyBridge / IvyBridge处理器(使用与NASM的汇编)可获得95%的峰值。 但是,除非我展开循环,否则使用Haswell I只能达到峰值的62%。 如果我展开16次,我得到92%。 我不明白这一点。 我决定使用NASM在汇编中编写我的function。 assembly中的主循环看起来像这样。 .L2: vmovaps ymm1, [rdi+rax] vfmadd231ps ymm1, ymm2, [rsi+rax] vmovaps [rdx+rax], ymm1 add rax, 32 jne .L2 在例子12.7-12.11的Agner […]
在Perl脚本中保持内存使用率低的一些好的技巧是什么? 我有兴趣学习如何保持我的内存占用尽可能低的系统取决于Perl程序。 我知道Perl在内存使用方面并不是很好,但是我想知道是否有改进它的提示。 那么,你可以做些什么来保持一个Perl脚本使用较less的内存。 我对任何build议感兴趣,无论是写代码的实际技巧,还是关于如何以不同方式编译Perl的技巧。 编辑赏金:我有一个perl程序,作为一个networking应用程序的服务器。 每个连接到它的客户端当前都有自己的subprocess。 我已经使用线程,而不是叉,但我一直无法确定,如果使用线程而不是福克斯实际上是更高效的内存。 我想尝试使用线程而不是叉子。 我相信在理论上应该节省内存使用。 在这方面我有几个问题: Perl中创build的线程是否阻止将Perl模块库复制到每个线程的内存中? 线程 (使用线程)是在Perl中创build线程的最有效的方法(或唯一的方法)吗? 在线程中,我可以指定一个stack_size参数,在指定这个值的时候应该考虑什么,以及它如何影响内存的使用? 使用Perl / Linux中的线程,在每个线程的基础上确定实际内存使用情况的最可靠方法是什么?
例如,如果我有两个情况下的枚举,它是否需要比布尔值更多的内存? 语言:Java,C ++