douqi0090 2014-09-04 06:51
浏览 66
已采纳

与C ++ / C相比的Golang内存布局

In golang, it seems there are no constructors, but it is suggested that you allocate an object of a struct type using a function, usually named by "New" + TypeName, for example

func NewRect(x,y, width, height float) *Rect {
     return &Rect(x,y,width, height)
}

However, I am not sure about the memory layout of Go. In C/C++, this kind of code means you return a pointer, which point to a temporary object because the variable is allocated on the stack, and the variable may be some trash after the function return. In Golang, do I have to worry such kind of thing? Because It seems no standard shows that what kind of data will be allocated on the stack vs what kind of data will be allocated on the heap.

As in Java, there seems to have a specific point out that the basic type such as int, float will be allocated on the stack, other object derived from the object will be allocated on the heap. In golang, is there a specific talk about this?

  • 写回答

1条回答 默认 最新

  • duanshang7007 2014-09-04 06:58
    关注

    The Composite Literal section mentions:

    Taking the address of a composite literal (§Address operators) generates a unique pointer to an instance of the literal's value.

    That means the pointer returned by the New function will be a valid one (allocated on the stack).
    Calls:

    In a function call, the function value and arguments are evaluated in the usual order.
    After they are evaluated, the parameters of the call are passed by value to the function and the called function begins execution.
    The return parameters of the function are passed by value back to the calling function when the function returns.

    You can see more in this answer and this thread.

    As mentioned in "Stack vs heap allocation of structs in Go, and how they relate to garbage collection":

    It's worth noting that the words "stack" and "heap" do not appear anywhere in the language spec.


    The blog post "Escape Analysis in Go" details what happens, mentioning the FAQ:

    When possible, the Go compilers will allocate variables that are local to a function in that function's stack frame.
    However, if the compiler cannot prove that the variable is not referenced after the function returns, then the compiler must allocate the variable on the garbage-collected heap to avoid dangling pointer errors.
    Also, if a local variable is very large, it might make more sense to store it on the heap rather than the stack.

    The blog post adds:

    The code that does the “escape analysis” lives in src/cmd/gc/esc.c.
    Conceptually, it tries to determine if a local variable escapes the current scope; the only two cases where this happens are when a variable’s address is returned, and when its address is assigned to a variable in an outer scope.
    If a variable escapes, it has to be allocated on the heap; otherwise, it’s safe to put it on the stack.

    Interestingly, this applies to new(T) allocations as well.
    If they don’t escape, they’ll end up being allocated on the stack. Here’s an example to clarify matters:

    var intPointerGlobal *int = nil
    
    func Foo() *int {
        anInt0 := 0
        anInt1 := new(int)
    
        anInt2 := 42
        intPointerGlobal = &anInt2
    
        anInt3 := 5
    
        return &anInt3
    }
    

    Above, anInt0 and anInt1 do not escape, so they are allocated on the stack;
    anInt2 and anInt3 escape, and are allocated on the heap.


    See also "Five things that make Go fast":

    Unlike C, which forces you to choose if a value will be stored on the heap, via malloc, or on the stack, by declaring it inside the scope of the function, Go implements an optimisation called escape analysis.

    Go’s optimisations are always enabled by default.
    You can see the compiler’s escape analysis and inlining decisions with the -gcflags=-m switch.

    Because escape analysis is performed at compile time, not run time, stack allocation will always be faster than heap allocation, no matter how efficient your garbage collector is.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 求解vmware的网络模式问题
  • ¥24 EFS加密后,在同一台电脑解密出错,证书界面找不到对应指纹的证书,未备份证书,求在原电脑解密的方法,可行即采纳
  • ¥15 springboot 3.0 实现Security 6.x版本集成
  • ¥15 PHP-8.1 镜像无法用dockerfile里的CMD命令启动 只能进入容器启动,如何解决?(操作系统-ubuntu)
  • ¥30 请帮我解决一下下面六个代码
  • ¥15 关于资源监视工具的e-care有知道的嘛
  • ¥35 MIMO天线稀疏阵列排布问题
  • ¥60 用visual studio编写程序,利用间接平差求解水准网
  • ¥15 Llama如何调用shell或者Python
  • ¥20 谁能帮我挨个解读这个php语言编的代码什么意思?