首页 > 系统相关 >【小记】如果 golang 内存不够了怎么办

【小记】如果 golang 内存不够了怎么办

时间:2023-02-03 00:34:17浏览次数:47  
标签:NULL npages oom value golang 内存 size 小记

在看 redis 1.0 源码时,总会看到需要申请内存的地方,如果申请不到需要大的内存就会返回 NULL,然后在调用层抛出 oom。
比如 listDup 中在复制特殊 value 或者加入新节点时都有可能返回 NULL

if (copy->dup) {
    value = copy->dup(node->value);
    if (value == NUL) {
        ...
        return NULL;
    }
}
...
if (listAddNodeTail(copy, value) == NULL) {
    ...
    return NULL;
}

调用层中发现复制失败,抛出 oom

c->reply = listDup(slave->reply);
if (!c->reply) oom("listDup copying slave reply list");

oom 中执行 abort()

static void oom(const char *msg) {
    fprintf(stderr, "%s: Out of memory\n",msg);
    fflush(stderr);
    sleep(1);
    abort();
}

然后我就想到了 golang 的 make/new,平时都不会遇到 oom 的情况,感觉每次 make/new 都会成功,并且这两个函数都没有特殊返回值来标识失败的情况,因此在底层应该是做了处理。
由于之前在 mapassign 中看到分配桶的情节,最终在 mallocgc 函数中找到了目标函数 allocLarge

// allocLarge allocates a span for a large object.
func (c *mcache) allocLarge(size uintptr, noscan bool) *mspan {
    if size+_PageSize < size {
        throw("out of memory")
    }
    npages := size >> _pageShift
    if size&_PageMask != 0 {
        npages++
    }
    // Deduct credit for this span allocation and sweep if
    // necessary. mHeap_Alloc will also sweep npages, so this only
    // pays the debt down to npage pages.
    deductSweepCredit(npages*_PageSize, npages)
    spc := makeSpanClass(0, noscan)
    s := mheap_.alloc(npages, spc)
    if s == nil {
    	throw("out of memory")
    }
    ...
}

throw 最终调用 fatalthrow

// fatalthrow implements an unrecoverable runtime throw. It freezes the
// system, prints stack traces starting from its caller, and terminates the
// process.

最终也是终止程序,看上去和 abort 一样
嗯,既然 golang 已经做了这部工作,那我就需要担心内存不够如何处理的问题了(虽然很大概率遇不到)

标签:NULL,npages,oom,value,golang,内存,size,小记
From: https://www.cnblogs.com/HelloEricy/p/17087826.html

相关文章

  • 内存分析 - 初始
    内存分析-初始内存内存栈堆栈、堆//1.声明数组//在栈中创建一个array的名字,这个时候array是空的,没有实际意义//这个时候的array就相当......
  • Golang入门第二天
    选择结构循环结构流程控制类型转换类型别名函数调用函数类型匿名函数和闭包回调函数packagemainimport( "fmt")//函数1funcdemo1(){ fmt.Println(......
  • [golang]filepath.Glob的缺陷,不支持多级目录
    最近在使用Gin框架的模板加载过程中,发现其对于多级子目录中的模板支持有问题(仅仅支持一级子目录),后经过查看其源码发现是filepath包的Glob方法的问题。下面先说结论:多......
  • 【C语言】memset() 内存填充块
    ......
  • Java内存模型之JMM
    Java内存模型之JMM问题你知道什么是Java内存模型JMM吗?JMM与volatile它们两个之间的关系?(下一章详细讲解)JMM有哪些特性or它的三大特性是什么?为什么要有JMM,它为......
  • Windbg下使用dump分析内存溢出
    分析简述 创建dump文件;通过 !address-summary 和 !eeheap-gc判断是否为内存泄漏;通过!dumpheap-stat观察出问题的类型;通过!dumpheap-mtMT号-minxxx来索引该类......
  • IOS逆向--恢复Dyld的内存加载方式
    之前我们一直在使用由dyld及其NSCreateObjectFileImage FromMemory/NSLinkModuleAPI方法所提供的Mach-O捆绑包的内存加载方式。虽然这些方法我们今天仍然还在使......
  • gbase资源组修改内存
    1)登录数据集市数据库gccli-ugbase-ppwd 2)查看有哪些数据库showdatabases; 3)选择数据库usegbase; 4)查看现有的资源池名与分配的内存量(单位是b)selectresou......
  • Golang入门第一天
    变量的使用自动推导类型多重赋值和匿名变量常量的使用多重变量或常量的定义iota枚举bool布尔类型浮点型字符类型字符串类型字符类型和字符串类型的区别复数类......
  • 在Runtime下,IL2CPP与Mono打包对应的PSS内存占用问题
    1)在Runtime下,IL2CPP与Mono打包对应的PSS内存占用问题​2)获得AssetBundle内部依赖关系的方法3)Unity2019StreamingMipmap在某些情况下采样等级错误4)根据RenderDoc的数据,计......