在看 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 已经做了这部工作,那我就需要担心内存不够如何处理的问题了(虽然很大概率遇不到)

【小记】如果 golang 内存不够了怎么办的更多相关文章

  1. golang内存分配

    golang内存分配 new一个对象的时候,入口函数是malloc.go中的newobject函数 func newobject(typ *_type) unsafe.Pointer { flags ...

  2. golang 内存监控

    golang 内存监控 - 简书 https://www.jianshu.com/p/38dc129b6870

  3. Golang内存管理

    Golang 内存管理 原文链接[http://legendtkl.com/2017/04/02/golang-alloc/] Golang 的内存管理基于 tcmalloc,可以说起点挺高的.但是 ...

  4. Golang内存模型

    Ref: https://golang.org/ref/mem 简介 golang内存模型,主要说明了如下问题.在一个goroutine中读取变量,而该变量是由其他goroutine赋值的,这种情况下 ...

  5. 记一次golang内存泄露

    记一次golang内存泄露 最近在QA环境上验证功能时,发现机器特别卡,查看系统内存,发现可用(available)内存仅剩200多M,通过对进程耗用内存进行排序,发现有一个名为application ...

  6. [golang]内存不断增长bytes.makeSlice

    ------------------------------------------ 2015.7月更新 后面发现这里其实有一个sb的问题,在于内存回收和释放. 每个http请求,都会带一个http. ...

  7. 图解golang内存分配机制 (转)

    一般程序的内存分配 在讲Golang的内存分配之前,让我们先来看看一般程序的内存分布情况: 以上是程序内存的逻辑分类情况. 我们再来看看一般程序的内存的真实(真实逻辑)图: Go的内存分配核心思想 G ...

  8. golang 内存模型

    1,是什么 是一套规范.内存操作指导 解决多线程编程的 程序的 原子性,有序性,可见性(主要)的问题. 多核操作系统,会存在缓存不一致的情况,说到底是一个同步的问题. 2, 内容 内存模型,除了定义了 ...

  9. Golang内存分配内置函数之new函数

    new函数用来分配内存,主要分配值类型,比如int.float32.struct等,返回的是指针 package main import ( "fmt" ) func main() ...

  10. golang 内存分析/动态追踪

    如果你的go程序是用http包启动的web服务器,你想查看自己的web服务器的状态.这个时候就可以选择net/http/pprof.你只需要引入包_"net/http/pprof" ...

随机推荐

  1. qt_2d画图

    qt中如何画图? 使用Qpainter类进行2D绘画 例如以下代码进行直线的绘制 QPainter painter(this);painter.setPen(Qt::red);painter.draw ...

  2. AppCrawler自动遍历工具,适用于移动端

    AppCrawler下载链接:https://github.com/seveniruby/AppCrawler,主要用途是回归遍历.原则从中间元素开始遍历 AppCrawler框架引擎 appium ...

  3. 0627.selenium请求库*2

    昨天已经介绍了关于selenium的简单基本基本使用--通过两种方式自动打开和关闭谷歌浏览器今天,我们将介绍的模块将是在昨天打开谷歌浏览器的基础上,打开某一个电商平台,并搜索某一个产品,利用前面学的知 ...

  4. 用xmind转换成excel表格

    我的版本是: XMind 8 Update 9 (R3.7.9.201912052356) 1.先下载一个xmind软件,并注册账号,建议最好用qq邮箱去注册 2.然后下载一个 XMindCrack. ...

  5. vscode中配置代码片段

    首先我们需要把要配置的代码复制一下,如: 然后我们进入https://snippet-generator.app/网站, 进入网站之后就把你复制的代码粘贴到左边的框里面,然后就是代码的类型和命名了 写 ...

  6. java-javaSE-泛型和反射

    泛型 什么是泛型 泛型,即"参数化类型".顾名思义,就是将类型参数化,然后在使用/调用时传入具体的类型(类型实参). 为什么使用泛型 泛型提高程序操作的可读性和安全性. 例如集合类 ...

  7. ptyhon基础课程_3

    14 综上练习题 评分规则: A:>=90 B:>=80 C:>=70 D:其他 用户输入成绩,根据成绩显示不同的级别 score = input ("请输入您的成绩:&q ...

  8. ubuntu常用操作

    Ubuntu22.04 server 创建随操作系统自动启动: 创建rc-local.service cp /lib/systemd/system/rc.-local.service /etc/sys ...

  9. 【Hive】元数据库部署的三种方式和选择【metaStore server】

    一.Derby 元数据使用之前,要在hive目录下执行schematool命令,进行初始化设置 bin/schematool -dbType derby -initSchema 启动hive后,可以用 ...

  10. ThinkPHP获取当前url

    $httpType = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTT ...