【golang】内存逃逸常见情况和避免方式

Python012

【golang】内存逃逸常见情况和避免方式,第1张

因为如果变量的内存发生逃逸,它的生命周期就是不可知的,其会被分配到堆上,而堆上分配内存不能像栈一样会自动释放,为了解放程序员双手,专注于业务的实现,go实现了gc垃圾回收机制,但gc会影响程序运行性能,所以要尽量减少程序的gc操作。

1、在方法内把局部变量指针返回,被外部引用,其生命周期大于栈,则溢出。

2、发送指针或带有指针的值到channel,因为编译时候无法知道那个goroutine会在channel接受数据,编译器无法知道什么时候释放。

3、在一个切片上存储指针或带指针的值。比如[]*string,导致切片内容逃逸,其引用值一直在堆上。

4、因为切片的append导致超出容量,切片重新分配地址,切片背后的存储基于运行时的数据进行扩充,就会在堆上分配。

5、在interface类型上调用方法,在Interface调用方法是动态调度的,只有在运行时才知道。

1、go语言的接口类型方法调用是动态,因此不能在编译阶段确定,所有类型结构转换成接口的过程会涉及到内存逃逸发生,在频次访问较高的函数尽量调用接口。

2、不要盲目使用变量指针作为参数,虽然减少了复制,但变量逃逸的开销更大。

3、预先设定好slice长度,避免频繁超出容量,重新分配。

CREATE TABLE #ta(A1 int,ID bigint NOT NULL IDENTITY(1,1))go

DECLARE @max AS INT, @rc AS INT

SET @max = 1000000

SET @rc = 1

INSERT INTO #ta(A1) select 1

WHILE @rc <ceiling(log(@max) / log(2))

BEGIN

INSERT INTO #ta(A1) SELECT 1 FROM #ta

SET @rc = @rc + 1

END

select @max = @max - @@IDENTITY

INSERT INTO #ta(A1)

SELECT 1 FROM #ta where id <= @max

insert into book3

select 'a'+ltrim(str(id)),'b'+ltrim(str(id)),'c'+ltrim(str(id)),'d'+ltrim(str(id)),'e'+ltrim(str(id)),'2-12-2012'

from #ta

出现此问题的原因是该计算机没有足够的内存来完成所请求的操作。

SQL Server 2000 报表服务的限制会导致报告处理绑定的内存的某些部分。例如对于查询结果处理和对象模型呈现是绑定的内存。

计算机没有足够的内存来完成所请求的操作,一种或多种以下条件: 报表是太大或太复杂。 其他正在运行的进程的开销是很高。 物理内存的计算机来说过小。