博客
关于我
善待内存
阅读量:484 次
发布时间:2019-03-06

本文共 1482 字,大约阅读时间需要 4 分钟。

内存分配与复制性能问题的深度分析

在实际开发中,内存分配和数据复制的效率往往成为性能瓶颈。本文将从内存分配机制和页面交换机制两个方面,分析一个现实场景下的性能问题,并探讨解决方案。

背景介绍

目前系统中有35块内存,每块大小为200M,均采用malloc分配。在使用过程中,这些内存块被部分填充,剩余空间保持空闲状态。随后,我们将这35块内存中的有数据部分复制到一个1G的大内存块中。已知有效数据总和不超过1G。

伪代码如下:

#define MAX_PER_BLOCK_MEM_SIZE (1024*1024*200)
#define MAX_TOTAL_BLOCK_MEM_SIZE (1024*1024*1024)
for (i = 0; i < 35; i++) {
mem[i] = malloc(MAX_PER_BLOCK_MEM_SIZE);
}
big_block = malloc(MAX_TOTAL_BLOCK_MEM_SIZE);
for (i = 0; i < 35; i++) {
put some data to mem[i];
len[i] = len(somedata);
}
for (i = 0; i < 35; i++) {
copyto(big_block, mem[i], len[i]);
}

问题分析

实际执行结果显示,复制35块内存到1G大内存块的操作耗时30秒,远超预期的1秒钟。这表明内存访问效率低下,可能存在以下两种原因:

  • 缓存缺失(Cache Miss)

    缓存缺失通常不会导致如此严重的性能下降。复制数据的过程中,缓存的命中率接近100%,而缓存写入操作即使占用Cache Capacity,也无法支持如此大的数据量。

  • 页面交换(Page Swap)

    页面交换是更有可能的原因。页面交换涉及到磁盘I/O操作,耗时较长。系统空闲内存约为8G,已申请内存总量为35*0.2G + 1G = 8G,刚好达到系统空闲内存上限。这表明页面交换频繁,导致性能大幅下降。

  • 内存分配机制的探讨

    操作系统内存管理分为两种主要模式:立即分配和懒惰分配。

  • 立即分配(Immediate Allocation)

    立即分配方式会预先分配空闲物理内存页。对于大块内存分配,系统可能缺乏可用物理页,导致页面交换频繁。例如,A进程分配8G内存后,B进程申请2G内存将无法获得物理页,系统需要触发页面交换。

  • 懒惰分配(Lazy Allocation)

    懒惰分配方式在内存分配时不立即分配物理页。访问时发生缺页中断,系统申请物理页并分配。这种方式保留了更多空闲物理页,但缺页中断会频繁发生,尤其是当大量小块内存被分配时。

  • 解决方案

    通过调整内存块大小和优化内存分配策略,可以有效缓解页面交换问题:

  • 减小内存块大小

    将每块内存从200M减小到120M。重复实验后显示,性能得到了显著提升。这种调整减少了页面交换的频率,使内存分配更加高效。

  • 优化内存分配策略

    系统应区分对待大内存和小内存分配。大内存块采用懒惰分配,小内存块则采用即时分配。这样可以在保证性能的同时,避免页面交换过于频繁。

  • 结论

    现有内存分配机制中,懒惰分配方式在大内存分配时存在性能开销问题。通过调整内存块大小和优化分配策略,可以有效减少页面交换的负面影响,提升整体性能。对于类似问题,建议深入研究内存管理算法,并结合实际应用场景进行优化。

    此外,建议查阅相关操作系统内核源码,了解具体内存分配和页面交换机制的实现细节,以便更好地进行系统性能调优。

    转载地址:http://tnwdz.baihongyu.com/

    你可能感兴趣的文章
    Python3连接MySQL
    查看>>
    Python关于isinstance函数的解析 | 附Demo(全)
    查看>>
    Python3:setup.py:完成所有任务的PIP安装(Build_ext+Install)
    查看>>
    python4.0 gil_Python 并发编程系列--1、浅谈GIL历史及对多线程的影响
    查看>>
    python60行绘图程序_天底下最简单的QT画图板,就一个类,60行代码
    查看>>
    Python: AES加密与解密
    查看>>
    Python: Range() 最大尺寸;动态的还是静态的?
    查看>>
    Python: Windows下用 multiprocessing 的深坑
    查看>>
    python:Could not find platform independent libraries <prefix>解决方法
    查看>>
    Python:datetime tzinfo 时区名称文档
    查看>>
    Python:deepcopy(list) vs new_list = old_list[:]
    查看>>
    Python:Google API - 从消息中获取 mimeTypes
    查看>>
    Python:Google API - 从消息中获取 mimeTypes
    查看>>
    Python:subprocess.call,stdout to file,stderr to file,在屏幕上实时显示stderr
    查看>>
    Python:TypeError:无法连接“str“和“int“对象
    查看>>
    Python:XPath 在 ElementTree 中不可用
    查看>>
    Python:从 FTP 服务器下载文件
    查看>>
    python:从列表中创建元组列表
    查看>>
    Python:从嵌套列表中删除重复项
    查看>>
    Python:从间隔映射到值
    查看>>