在看 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. dom4j解析和生成xml文件

    解析xml大致步骤: 1: 创建SAXReader: 2: 使用SAXReader解析指定的xml文档信息,并返回对应Document对象.Document对象中就包含了该xml文中的所有信息以及结构 ...

  2. 【Nginx】优化,增加线程

    https://blog.csdn.net/cnskylee/article/details/127645806 众所周知,Nginx一款体积小巧,但是性能强大的软负载,主要被用作后端服务和应用的反向 ...

  3. 增加select的option之间的间距

    直接设置option的上下内边距即可,即padding-top和padding-bottom.

  4. Web文件上传模块 Plupload

    Plupload 是一个Web浏览器上的界面友好的文件上传模块,可显示上传进度.图像自动缩略和上传分块.可同时上传多个文件. 示例代码: <!-- Load Queue widget CSS a ...

  5. SSM整合【狂神说】

    1.环境要求 IDEA MySQL 5.7 Tomcat 9 Maven 3.6 要求: 需要熟练掌握MySQL数据库,Spring,Java Web及Mybatis知识,简单的前端知识. 2.数据库 ...

  6. (jmeter笔记) websocket接口测试

    1.在进程选择WebSocket Sampler 2.Websocket Sampler 界面 webserver Server Name or IP:输入连接的websocket服务器ip Port ...

  7. docker部署rocketmq

    docker pull foxiswho/rocketmq:server-4.7.0  (拉取镜像) docker pull foxiswho/rocketmq:broker-4.7.0 (拉取镜像) ...

  8. Kubernetes--Pod存活性探测(设置HTTP探针)

    基于HTTP的探测(HTTPGetAction)向目标容器发起一个HTTP请求,根据其响应码进行结果判定,响应码形如2xx或者3xx时表示检测通过."sepc.containers.live ...

  9. Java笔记_成员方法传参机制

    成员方法传参机制(非常重要) Parameter(参数).Method(方法).Exercise(练习) 基本数据类型的传参机制 看一下案例,将main中的值传递给类中对象 /** * @ClassN ...

  10. Laravel ORM 常用方法

    1. 数据查询 ->find($id);  //需要一个主键$id并返回一个模型对象.若不存在则返回null ->findOrFail($id);  //需要一个主键$id并返回一个模型对 ...