V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
LuckyPocketWatch
V2EX  ›  Linux

申请大内存,程序直接被系统干掉,求指教

  •  
  •   LuckyPocketWatch · 2023-09-19 22:15:23 +08:00 · 2195 次点击
    这是一个创建于 460 天前的主题,其中的信息可能已经有所发展或是发生改变。
    std::vector<Dev> allDevs;
    for(std::size_t i = 0 ; i < DEVLENGHT ; ++i)
        allDevs.push_back(Dev());
    

    其中 class Dev 包含数据为 6 个 int 和若干成员函数,系统为 64 位的 linux ,int 的长度设为 4 字节,机器的物理内存位 256G ,使用 g++8.3 编译以上代码,然后运行,当 DEVLENGHT 设为 10 亿的时候,系统就会直接干掉程序

    12 条回复    2023-09-20 08:50:43 +08:00
    huahsiung
        1
    huahsiung  
       2023-09-19 22:30:33 +08:00
    我是写 C 的,偶然也写 C++,不知道 gcc 有些时候为什么 malloc()后不用的内存会被优化掉。建议是可以分片,不超过 unsigned int 的最大值( 2^32=4G )。这样在服务器上连续运行了 4 个月,没问题。就是编写的时候管理麻烦。

    python 倒没有这个问题。深度学习申请 128G 都不会 kill 。

    话说我是直接用 unsigned int 当指针用的。要用的时候,用(char *)或者(void *)强行转换一下。
    lsry
        2
    lsry  
       2023-09-19 22:39:54 +08:00   ❤️ 3
    首先你的十亿数据,经计算大概要 223G 内存,但是你没有预先分配内存,而是让 vector 自增长,在最后一次分配时就需要 223 * 1.5 = 335G ,这就超过了你的内存限制。
    lcdtyph
        3
    lcdtyph  
       2023-09-19 22:41:49 +08:00 via iPhone
    lz 可能要去搜索 oom killer
    LGA1150
        4
    LGA1150  
       2023-09-19 22:42:37 +08:00 via Android
    看内核日志,有没有触发 oom reaper
    geelaw
        5
    geelaw  
       2023-09-19 22:43:05 +08:00 via iPhone
    怎么确定是系统结束了进程,还是进程结束了自己?你试过 try catch 了吗? allDevs.max_size() 是多少?
    kneo
        6
    kneo  
       2023-09-19 22:49:10 +08:00 via Android
    难道你想让系统分配几百个 g 的虚拟内存继续帮你搞吗?
    leonshaw
        7
    leonshaw  
       2023-09-19 22:52:14 +08:00 via Android
    试试先 reserve capacity
    cnbatch
        8
    cnbatch  
       2023-09-19 23:54:14 +08:00
    @lsry 应该是 22.3G 吧

    24 Bytes ×10'0000'0000 = 240'0000'0000 Bytes = 23437500 KiB = 22888.18359375 MiB = 22.35174179077148 GiB
    cnbatch
        9
    cnbatch  
       2023-09-20 00:00:44 +08:00
    不知道 OP 的系统版本是什么,我用自己的台式机试了下并没有 OOM ,正常运行、正常退出。
    我台式机安装的 Linux 系统比较小众,是 OpenMandriva ,版本号 16.0.6-3 ,编译器是 clang 16.0.6

    同时我还开着 KDE System Monitor ,观察到测试时最高内存占用会升到 25G 左右

    C++代码如下:

    #include <iostream>
    #include <vector>

    constexpr size_t DEVLENGHT = 1000000000ULL;

    class Dev
    {
    int a;
    int b;
    int c;
    int d;
    int e;
    int f;
    public:
    Dev() : a(0), b(0), c(0), d(0), e(0), f(0) {}
    };

    int main()
    {
    std::vector<Dev> allDevs;
    for(std::size_t i = 0 ; i < DEVLENGHT ; ++i)
    {
    try
    {
    allDevs.push_back(Dev());
    }
    catch (std::exception &ex)
    {
    std::cout << ex.what() << std::endl;
    std::cout << i << std::endl;
    break;
    }
    }
    }
    lsry
        10
    lsry  
       2023-09-20 00:19:42 +08:00
    @cnbatch 是十亿个,你算成了一亿
    cnbatch
        11
    cnbatch  
       2023-09-20 00:25:30 +08:00
    @lsry
    那我换个写法

    千分位分隔:
    24 Bytes ×1'000'000'000 = 24'000'000'000 Bytes = 23437500 KiB = 22888.18359375 MiB = 22.35174179077148 GiB

    One billion ,即十亿

    万分位分隔:
    24 Bytes ×10'0000'0000 = 240'0000'0000 Bytes = 23437500 KiB = 22888.18359375 MiB = 22.35174179077148 GiB
    xiaofan2
        12
    xiaofan2  
       2023-09-20 08:50:43 +08:00
    dmesg -T 看看 oom killer 日志,另外 google 下 oom killer 机制
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3255 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 12:11 · PVG 20:11 · LAX 04:11 · JFK 07:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.