首页 > 其他 > 详细

erlang的GC(一)

时间:2015-09-01 02:10:27      阅读:452      评论:0      收藏:0      [点我收藏+]

?

?

今天来说一下长期运行的项目会有内存越用越大的情况的发生原因。中所周知,erlang是运行在虚拟机上的,他的GC不是全局的而是针对进程单独GC。所以GC时整个系统不会产生中断,这是他的优点。那么既然有GC为什么还会有内存的增长呢??

当我们运行这个命令(erlang:memory())会发现,内存的增长主要是在binary上。要找到这个原因,就要知道GC里关于binary的处理。

在erlang中,binary的存储位置一共有两处:

1.size<=64K的binary存储在每个进程单独的heap(堆)中。这种bianry叫做Heap-binary。

2.size>64K的binary存储在虚拟机分配出来单独的heap(堆)中,而用到这个binary的进程的heap中只有一个这个binary的引用。这种binary叫做Refc-binaries。

在进程进行GC的时候Heap-binary会随着GC而被释放掉,因为他是只属于这个进程的。相对应的这个进程heap中存储的Refc-binary也会被释放掉,但是其引用的元binary不会被释放,除非所有引用过这个Refc-binary的进程都进行GC后才会被释放。

这里说一下为什么Refc-binaries叫这个名字呢?这个名字全称是Reference-counted-binary,每当有个进程用到这个binary时,除了在自己进程heap中创建这个binary的引用以外,还要把记录这个binary的引用次数+1。只有当这个binary的引用次数为0的时候,才会把这个binary从专门的heap中释放掉。

在我们写erlang代码的时候,很容易遇到这种情况,<<A:8, B:16>> = C.在这里C本身是一个binary,A和B是C的sub-binary,在这个匹配语句中,erlang的VM不会创建2个新的binary,而是对C创建两个引用。这种引用叫做sub-binary。所以在VM中一共有4中binary,分别是:Heap-binary,Heap-binary的sub-binary,Refc-binary,Refc-binary的sub-binary。

而不论是Refc-binary还是Refc-binary的sub-binary,这两种binary都适用刚才说的Refc的GC规则,所以才会导致erlang项目在长期运行后,内存会出现越用越大的情况。具体原因可以举个例子,如果系统中的某个erlang进程起到类似路由的功能,很多Refc-binary的传递都要到这个进程中中转,结果其实这个进程不会操作这些Refc-binary,而由于这个进程基本什么都不干,仅仅中转一下消息所以基本不会有GC的机会,导致了系统中的大量Refc-binary无法得到释放,所以系统内存binary会越用越大。

针对这种情况怎么解决呢?

在创建这些“关键”进程的时候,在选项中加入{fullsweep_after, 0},这个选项的意思是如果有没用的binary,会立马释放掉。

erlang的GC(一)

原文:http://wudixiaotie.iteye.com/blog/2239734

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!