Error[8]: Undefined offset: 6, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

Go中结构堆栈vs堆分配,以及它们与垃圾回收的关系

值得注意的是,在语言规范中,“ stack”和“ heap”一词没有出现。您的问题用“ …在堆栈上声明”和“
…在堆栈上声明”来表述,但请注意,Go声明语法对堆栈或堆没有任何说明。

从技术上讲,这使您对所有问题的答案都依赖于实现。当然,实际上,有一个堆栈(每个goroutine!)和一个堆,有些东西在堆栈上,有些东西在堆栈上。在某些情况下,编译器遵循严格的规则(例如“

new
始终在堆上分配”),而在其他情况下,编译器执行“转义分析”来确定对象是否可以存在于堆栈中,或者是否必须在堆中进行分配。

在示例2中,转义分析将显示指向结构转义的指针,因此编译器将不得不分配该结构。我认为,在这种情况下,Go的当前实现遵循严格的规则,即,如果地址从结构的任何部分获取,则结构将进入堆。

对于问题3,我们可能会对术语感到困惑。Go中的所有内容都是按值传递的,没有按引用传递的。在这里,您将返回一个指针值。指针的意义是什么?考虑对示例的以下修改:

type MyStructType struct{}func myFunction1() (*MyStructType, error) {    var chunk *MyStructType = new(MyStructType)    // ...    return chunk, nil}func myFunction2() (MyStructType, error) {    var chunk MyStructType    // ...    return chunk, nil}type bigStruct struct {    lots [1e6]float64}func myFunction3() (bigStruct, error) {    var chunk bigStruct    // ...    return chunk, nil}

我修改了myFunction2以返回结构而不是结构的地址。现在比较myFunction1和myFunction2的程序集输出,

--- prog list "myFunction1" ---0000 (s.go:5) TEXT    myFunction1+0(SB),-240001 (s.go:6) MOVQ    $type."".MyStructType+0(SB),(SP)0002 (s.go:6) CALL    ,runtime.new+0(SB)0003 (s.go:6) MOVQ    8(SP),AX0004 (s.go:8) MOVQ    AX,.noname+0(FP)0005 (s.go:8) MOVQ    
myStructType。对runtime.new的调用已消失,在某些情况下这将是一件好事。等等,这是myFunction3,
,.noname+8(FP)0006 (s.go:8) MOVQ
--- prog list "myFunction3" ---0016 (s.go:21) TEXT    myFunction3+0(SB),00000-80000160017 (s.go:22) LEAQ    chunk+-8000000(SP),DI0018 (s.go:22) MOVQ    [+++],AX0019 (s.go:22) MOVQ    00000,CX0020 (s.go:22) REP     ,0021 (s.go:22) STOSQ   ,0022 (s.go:24) LEAQ    chunk+-8000000(SP),SI0023 (s.go:24) LEAQ    .noname+0(FP),DI0024 (s.go:24) MOVQ    00000,CX0025 (s.go:24) REP     ,0026 (s.go:24) MOVSQ   ,0027 (s.go:24) MOVQ    [+++],.noname+8000000(FP)0028 (s.go:24) MOVQ    [+++],.noname+8000008(FP)0029 (s.go:24) RET     ,
,.noname+16(FP)0007 (s.go:8) RET ,--- prog list "myFunction2" ---0008 (s.go:11) TEXT myFunction2+0(SB),[+++]-160009 (s.go:12) LEAQ chunk+0(SP),DI0010 (s.go:12) MOVQ [+++],AX0011 (s.go:14) LEAQ .noname+0(FP),BX0012 (s.go:14) LEAQ chunk+0(SP),BX0013 (s.go:14) MOVQ [+++],.noname+0(FP)0014 (s.go:14) MOVQ [+++],.noname+8(FP)0015 (s.go:14) RET ,

不必担心这里的myFunction1输出与peterSO的(出色)答案不同。我们显然正在运行不同的编译器。否则,请参见我修改了myFunction2以返回myStructType而不是*[+++]

[+++]

仍然没有调用runtime.new,是的,它确实可以按值返回8MB对象。它有效,但是您通常不希望这样做。这里的指针指向是避免推送约8MB的对象。



)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 7, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

Go中结构堆栈vs堆分配,以及它们与垃圾回收的关系

值得注意的是,在语言规范中,“ stack”和“ heap”一词没有出现。您的问题用“ …在堆栈上声明”和“
…在堆栈上声明”来表述,但请注意,Go声明语法对堆栈或堆没有任何说明。

从技术上讲,这使您对所有问题的答案都依赖于实现。当然,实际上,有一个堆栈(每个goroutine!)和一个堆,有些东西在堆栈上,有些东西在堆栈上。在某些情况下,编译器遵循严格的规则(例如“

new
始终在堆上分配”),而在其他情况下,编译器执行“转义分析”来确定对象是否可以存在于堆栈中,或者是否必须在堆中进行分配。

在示例2中,转义分析将显示指向结构转义的指针,因此编译器将不得不分配该结构。我认为,在这种情况下,Go的当前实现遵循严格的规则,即,如果地址从结构的任何部分获取,则结构将进入堆。

对于问题3,我们可能会对术语感到困惑。Go中的所有内容都是按值传递的,没有按引用传递的。在这里,您将返回一个指针值。指针的意义是什么?考虑对示例的以下修改:

type MyStructType struct{}func myFunction1() (*MyStructType, error) {    var chunk *MyStructType = new(MyStructType)    // ...    return chunk, nil}func myFunction2() (MyStructType, error) {    var chunk MyStructType    // ...    return chunk, nil}type bigStruct struct {    lots [1e6]float64}func myFunction3() (bigStruct, error) {    var chunk bigStruct    // ...    return chunk, nil}

我修改了myFunction2以返回结构而不是结构的地址。现在比较myFunction1和myFunction2的程序集输出,

--- prog list "myFunction1" ---0000 (s.go:5) TEXT    myFunction1+0(SB),-240001 (s.go:6) MOVQ    $type."".MyStructType+0(SB),(SP)0002 (s.go:6) CALL    ,runtime.new+0(SB)0003 (s.go:6) MOVQ    8(SP),AX0004 (s.go:8) MOVQ    AX,.noname+0(FP)0005 (s.go:8) MOVQ    
myStructType。对runtime.new的调用已消失,在某些情况下这将是一件好事。等等,这是myFunction3,
,.noname+8(FP)0006 (s.go:8) MOVQ
--- prog list "myFunction3" ---0016 (s.go:21) TEXT    myFunction3+0(SB),00000-80000160017 (s.go:22) LEAQ    chunk+-8000000(SP),DI0018 (s.go:22) MOVQ    ,AX0019 (s.go:22) MOVQ    00000,CX0020 (s.go:22) REP     ,0021 (s.go:22) STOSQ   ,0022 (s.go:24) LEAQ    chunk+-8000000(SP),SI0023 (s.go:24) LEAQ    .noname+0(FP),DI0024 (s.go:24) MOVQ    00000,CX0025 (s.go:24) REP     ,0026 (s.go:24) MOVSQ   ,0027 (s.go:24) MOVQ    [+++],.noname+8000000(FP)0028 (s.go:24) MOVQ    [+++],.noname+8000008(FP)0029 (s.go:24) RET     ,
,.noname+16(FP)0007 (s.go:8) RET ,--- prog list "myFunction2" ---0008 (s.go:11) TEXT myFunction2+0(SB),[+++]-160009 (s.go:12) LEAQ chunk+0(SP),DI0010 (s.go:12) MOVQ [+++],AX0011 (s.go:14) LEAQ .noname+0(FP),BX0012 (s.go:14) LEAQ chunk+0(SP),BX0013 (s.go:14) MOVQ [+++],.noname+0(FP)0014 (s.go:14) MOVQ [+++],.noname+8(FP)0015 (s.go:14) RET ,

不必担心这里的myFunction1输出与peterSO的(出色)答案不同。我们显然正在运行不同的编译器。否则,请参见我修改了myFunction2以返回myStructType而不是*[+++]

[+++]

仍然没有调用runtime.new,是的,它确实可以按值返回8MB对象。它有效,但是您通常不希望这样做。这里的指针指向是避免推送约8MB的对象。



)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 8, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

Go中结构堆栈vs堆分配,以及它们与垃圾回收的关系

值得注意的是,在语言规范中,“ stack”和“ heap”一词没有出现。您的问题用“ …在堆栈上声明”和“
…在堆栈上声明”来表述,但请注意,Go声明语法对堆栈或堆没有任何说明。

从技术上讲,这使您对所有问题的答案都依赖于实现。当然,实际上,有一个堆栈(每个goroutine!)和一个堆,有些东西在堆栈上,有些东西在堆栈上。在某些情况下,编译器遵循严格的规则(例如“

new
始终在堆上分配”),而在其他情况下,编译器执行“转义分析”来确定对象是否可以存在于堆栈中,或者是否必须在堆中进行分配。

在示例2中,转义分析将显示指向结构转义的指针,因此编译器将不得不分配该结构。我认为,在这种情况下,Go的当前实现遵循严格的规则,即,如果地址从结构的任何部分获取,则结构将进入堆。

对于问题3,我们可能会对术语感到困惑。Go中的所有内容都是按值传递的,没有按引用传递的。在这里,您将返回一个指针值。指针的意义是什么?考虑对示例的以下修改:

type MyStructType struct{}func myFunction1() (*MyStructType, error) {    var chunk *MyStructType = new(MyStructType)    // ...    return chunk, nil}func myFunction2() (MyStructType, error) {    var chunk MyStructType    // ...    return chunk, nil}type bigStruct struct {    lots [1e6]float64}func myFunction3() (bigStruct, error) {    var chunk bigStruct    // ...    return chunk, nil}

我修改了myFunction2以返回结构而不是结构的地址。现在比较myFunction1和myFunction2的程序集输出,

--- prog list "myFunction1" ---0000 (s.go:5) TEXT    myFunction1+0(SB),-240001 (s.go:6) MOVQ    $type."".MyStructType+0(SB),(SP)0002 (s.go:6) CALL    ,runtime.new+0(SB)0003 (s.go:6) MOVQ    8(SP),AX0004 (s.go:8) MOVQ    AX,.noname+0(FP)0005 (s.go:8) MOVQ    
myStructType。对runtime.new的调用已消失,在某些情况下这将是一件好事。等等,这是myFunction3,
,.noname+8(FP)0006 (s.go:8) MOVQ
--- prog list "myFunction3" ---0016 (s.go:21) TEXT    myFunction3+0(SB),00000-80000160017 (s.go:22) LEAQ    chunk+-8000000(SP),DI0018 (s.go:22) MOVQ    ,AX0019 (s.go:22) MOVQ    00000,CX0020 (s.go:22) REP     ,0021 (s.go:22) STOSQ   ,0022 (s.go:24) LEAQ    chunk+-8000000(SP),SI0023 (s.go:24) LEAQ    .noname+0(FP),DI0024 (s.go:24) MOVQ    00000,CX0025 (s.go:24) REP     ,0026 (s.go:24) MOVSQ   ,0027 (s.go:24) MOVQ    ,.noname+8000000(FP)0028 (s.go:24) MOVQ    [+++],.noname+8000008(FP)0029 (s.go:24) RET     ,
,.noname+16(FP)0007 (s.go:8) RET ,--- prog list "myFunction2" ---0008 (s.go:11) TEXT myFunction2+0(SB),[+++]-160009 (s.go:12) LEAQ chunk+0(SP),DI0010 (s.go:12) MOVQ [+++],AX0011 (s.go:14) LEAQ .noname+0(FP),BX0012 (s.go:14) LEAQ chunk+0(SP),BX0013 (s.go:14) MOVQ [+++],.noname+0(FP)0014 (s.go:14) MOVQ [+++],.noname+8(FP)0015 (s.go:14) RET ,

不必担心这里的myFunction1输出与peterSO的(出色)答案不同。我们显然正在运行不同的编译器。否则,请参见我修改了myFunction2以返回myStructType而不是*[+++]

[+++]

仍然没有调用runtime.new,是的,它确实可以按值返回8MB对象。它有效,但是您通常不希望这样做。这里的指针指向是避免推送约8MB的对象。



)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 9, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

Go中结构堆栈vs堆分配,以及它们与垃圾回收的关系

值得注意的是,在语言规范中,“ stack”和“ heap”一词没有出现。您的问题用“ …在堆栈上声明”和“
…在堆栈上声明”来表述,但请注意,Go声明语法对堆栈或堆没有任何说明。

从技术上讲,这使您对所有问题的答案都依赖于实现。当然,实际上,有一个堆栈(每个goroutine!)和一个堆,有些东西在堆栈上,有些东西在堆栈上。在某些情况下,编译器遵循严格的规则(例如“

new
始终在堆上分配”),而在其他情况下,编译器执行“转义分析”来确定对象是否可以存在于堆栈中,或者是否必须在堆中进行分配。

在示例2中,转义分析将显示指向结构转义的指针,因此编译器将不得不分配该结构。我认为,在这种情况下,Go的当前实现遵循严格的规则,即,如果地址从结构的任何部分获取,则结构将进入堆。

对于问题3,我们可能会对术语感到困惑。Go中的所有内容都是按值传递的,没有按引用传递的。在这里,您将返回一个指针值。指针的意义是什么?考虑对示例的以下修改:

type MyStructType struct{}func myFunction1() (*MyStructType, error) {    var chunk *MyStructType = new(MyStructType)    // ...    return chunk, nil}func myFunction2() (MyStructType, error) {    var chunk MyStructType    // ...    return chunk, nil}type bigStruct struct {    lots [1e6]float64}func myFunction3() (bigStruct, error) {    var chunk bigStruct    // ...    return chunk, nil}

我修改了myFunction2以返回结构而不是结构的地址。现在比较myFunction1和myFunction2的程序集输出,

--- prog list "myFunction1" ---0000 (s.go:5) TEXT    myFunction1+0(SB),-240001 (s.go:6) MOVQ    $type."".MyStructType+0(SB),(SP)0002 (s.go:6) CALL    ,runtime.new+0(SB)0003 (s.go:6) MOVQ    8(SP),AX0004 (s.go:8) MOVQ    AX,.noname+0(FP)0005 (s.go:8) MOVQ    
myStructType。对runtime.new的调用已消失,在某些情况下这将是一件好事。等等,这是myFunction3,
,.noname+8(FP)0006 (s.go:8) MOVQ
--- prog list "myFunction3" ---0016 (s.go:21) TEXT    myFunction3+0(SB),00000-80000160017 (s.go:22) LEAQ    chunk+-8000000(SP),DI0018 (s.go:22) MOVQ    ,AX0019 (s.go:22) MOVQ    00000,CX0020 (s.go:22) REP     ,0021 (s.go:22) STOSQ   ,0022 (s.go:24) LEAQ    chunk+-8000000(SP),SI0023 (s.go:24) LEAQ    .noname+0(FP),DI0024 (s.go:24) MOVQ    00000,CX0025 (s.go:24) REP     ,0026 (s.go:24) MOVSQ   ,0027 (s.go:24) MOVQ    ,.noname+8000000(FP)0028 (s.go:24) MOVQ    ,.noname+8000008(FP)0029 (s.go:24) RET     ,
,.noname+16(FP)0007 (s.go:8) RET ,--- prog list "myFunction2" ---0008 (s.go:11) TEXT myFunction2+0(SB),[+++]-160009 (s.go:12) LEAQ chunk+0(SP),DI0010 (s.go:12) MOVQ [+++],AX0011 (s.go:14) LEAQ .noname+0(FP),BX0012 (s.go:14) LEAQ chunk+0(SP),BX0013 (s.go:14) MOVQ [+++],.noname+0(FP)0014 (s.go:14) MOVQ [+++],.noname+8(FP)0015 (s.go:14) RET ,

不必担心这里的myFunction1输出与peterSO的(出色)答案不同。我们显然正在运行不同的编译器。否则,请参见我修改了myFunction2以返回myStructType而不是*[+++]

[+++]

仍然没有调用runtime.new,是的,它确实可以按值返回8MB对象。它有效,但是您通常不希望这样做。这里的指针指向是避免推送约8MB的对象。



)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 10, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

Go中结构堆栈vs堆分配,以及它们与垃圾回收的关系

值得注意的是,在语言规范中,“ stack”和“ heap”一词没有出现。您的问题用“ …在堆栈上声明”和“
…在堆栈上声明”来表述,但请注意,Go声明语法对堆栈或堆没有任何说明。

从技术上讲,这使您对所有问题的答案都依赖于实现。当然,实际上,有一个堆栈(每个goroutine!)和一个堆,有些东西在堆栈上,有些东西在堆栈上。在某些情况下,编译器遵循严格的规则(例如“

new
始终在堆上分配”),而在其他情况下,编译器执行“转义分析”来确定对象是否可以存在于堆栈中,或者是否必须在堆中进行分配。

在示例2中,转义分析将显示指向结构转义的指针,因此编译器将不得不分配该结构。我认为,在这种情况下,Go的当前实现遵循严格的规则,即,如果地址从结构的任何部分获取,则结构将进入堆。

对于问题3,我们可能会对术语感到困惑。Go中的所有内容都是按值传递的,没有按引用传递的。在这里,您将返回一个指针值。指针的意义是什么?考虑对示例的以下修改:

type MyStructType struct{}func myFunction1() (*MyStructType, error) {    var chunk *MyStructType = new(MyStructType)    // ...    return chunk, nil}func myFunction2() (MyStructType, error) {    var chunk MyStructType    // ...    return chunk, nil}type bigStruct struct {    lots [1e6]float64}func myFunction3() (bigStruct, error) {    var chunk bigStruct    // ...    return chunk, nil}

我修改了myFunction2以返回结构而不是结构的地址。现在比较myFunction1和myFunction2的程序集输出,

--- prog list "myFunction1" ---0000 (s.go:5) TEXT    myFunction1+0(SB),-240001 (s.go:6) MOVQ    $type."".MyStructType+0(SB),(SP)0002 (s.go:6) CALL    ,runtime.new+0(SB)0003 (s.go:6) MOVQ    8(SP),AX0004 (s.go:8) MOVQ    AX,.noname+0(FP)0005 (s.go:8) MOVQ    
myStructType。对runtime.new的调用已消失,在某些情况下这将是一件好事。等等,这是myFunction3,
,.noname+8(FP)0006 (s.go:8) MOVQ
--- prog list "myFunction3" ---0016 (s.go:21) TEXT    myFunction3+0(SB),00000-80000160017 (s.go:22) LEAQ    chunk+-8000000(SP),DI0018 (s.go:22) MOVQ    ,AX0019 (s.go:22) MOVQ    00000,CX0020 (s.go:22) REP     ,0021 (s.go:22) STOSQ   ,0022 (s.go:24) LEAQ    chunk+-8000000(SP),SI0023 (s.go:24) LEAQ    .noname+0(FP),DI0024 (s.go:24) MOVQ    00000,CX0025 (s.go:24) REP     ,0026 (s.go:24) MOVSQ   ,0027 (s.go:24) MOVQ    ,.noname+8000000(FP)0028 (s.go:24) MOVQ    ,.noname+8000008(FP)0029 (s.go:24) RET     ,
,.noname+16(FP)0007 (s.go:8) RET ,--- prog list "myFunction2" ---0008 (s.go:11) TEXT myFunction2+0(SB),-160009 (s.go:12) LEAQ chunk+0(SP),DI0010 (s.go:12) MOVQ [+++],AX0011 (s.go:14) LEAQ .noname+0(FP),BX0012 (s.go:14) LEAQ chunk+0(SP),BX0013 (s.go:14) MOVQ [+++],.noname+0(FP)0014 (s.go:14) MOVQ [+++],.noname+8(FP)0015 (s.go:14) RET ,

不必担心这里的myFunction1输出与peterSO的(出色)答案不同。我们显然正在运行不同的编译器。否则,请参见我修改了myFunction2以返回myStructType而不是*[+++]

[+++]

仍然没有调用runtime.new,是的,它确实可以按值返回8MB对象。它有效,但是您通常不希望这样做。这里的指针指向是避免推送约8MB的对象。



)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 11, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

Go中结构堆栈vs堆分配,以及它们与垃圾回收的关系

值得注意的是,在语言规范中,“ stack”和“ heap”一词没有出现。您的问题用“ …在堆栈上声明”和“
…在堆栈上声明”来表述,但请注意,Go声明语法对堆栈或堆没有任何说明。

从技术上讲,这使您对所有问题的答案都依赖于实现。当然,实际上,有一个堆栈(每个goroutine!)和一个堆,有些东西在堆栈上,有些东西在堆栈上。在某些情况下,编译器遵循严格的规则(例如“

new
始终在堆上分配”),而在其他情况下,编译器执行“转义分析”来确定对象是否可以存在于堆栈中,或者是否必须在堆中进行分配。

在示例2中,转义分析将显示指向结构转义的指针,因此编译器将不得不分配该结构。我认为,在这种情况下,Go的当前实现遵循严格的规则,即,如果地址从结构的任何部分获取,则结构将进入堆。

对于问题3,我们可能会对术语感到困惑。Go中的所有内容都是按值传递的,没有按引用传递的。在这里,您将返回一个指针值。指针的意义是什么?考虑对示例的以下修改:

type MyStructType struct{}func myFunction1() (*MyStructType, error) {    var chunk *MyStructType = new(MyStructType)    // ...    return chunk, nil}func myFunction2() (MyStructType, error) {    var chunk MyStructType    // ...    return chunk, nil}type bigStruct struct {    lots [1e6]float64}func myFunction3() (bigStruct, error) {    var chunk bigStruct    // ...    return chunk, nil}

我修改了myFunction2以返回结构而不是结构的地址。现在比较myFunction1和myFunction2的程序集输出,

--- prog list "myFunction1" ---0000 (s.go:5) TEXT    myFunction1+0(SB),-240001 (s.go:6) MOVQ    $type."".MyStructType+0(SB),(SP)0002 (s.go:6) CALL    ,runtime.new+0(SB)0003 (s.go:6) MOVQ    8(SP),AX0004 (s.go:8) MOVQ    AX,.noname+0(FP)0005 (s.go:8) MOVQ    
myStructType。对runtime.new的调用已消失,在某些情况下这将是一件好事。等等,这是myFunction3,
,.noname+8(FP)0006 (s.go:8) MOVQ
--- prog list "myFunction3" ---0016 (s.go:21) TEXT    myFunction3+0(SB),00000-80000160017 (s.go:22) LEAQ    chunk+-8000000(SP),DI0018 (s.go:22) MOVQ    ,AX0019 (s.go:22) MOVQ    00000,CX0020 (s.go:22) REP     ,0021 (s.go:22) STOSQ   ,0022 (s.go:24) LEAQ    chunk+-8000000(SP),SI0023 (s.go:24) LEAQ    .noname+0(FP),DI0024 (s.go:24) MOVQ    00000,CX0025 (s.go:24) REP     ,0026 (s.go:24) MOVSQ   ,0027 (s.go:24) MOVQ    ,.noname+8000000(FP)0028 (s.go:24) MOVQ    ,.noname+8000008(FP)0029 (s.go:24) RET     ,
,.noname+16(FP)0007 (s.go:8) RET ,--- prog list "myFunction2" ---0008 (s.go:11) TEXT myFunction2+0(SB),-160009 (s.go:12) LEAQ chunk+0(SP),DI0010 (s.go:12) MOVQ ,AX0011 (s.go:14) LEAQ .noname+0(FP),BX0012 (s.go:14) LEAQ chunk+0(SP),BX0013 (s.go:14) MOVQ [+++],.noname+0(FP)0014 (s.go:14) MOVQ [+++],.noname+8(FP)0015 (s.go:14) RET ,

不必担心这里的myFunction1输出与peterSO的(出色)答案不同。我们显然正在运行不同的编译器。否则,请参见我修改了myFunction2以返回myStructType而不是*[+++]

[+++]

仍然没有调用runtime.new,是的,它确实可以按值返回8MB对象。它有效,但是您通常不希望这样做。这里的指针指向是避免推送约8MB的对象。



)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 12, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

Go中结构堆栈vs堆分配,以及它们与垃圾回收的关系

值得注意的是,在语言规范中,“ stack”和“ heap”一词没有出现。您的问题用“ …在堆栈上声明”和“
…在堆栈上声明”来表述,但请注意,Go声明语法对堆栈或堆没有任何说明。

从技术上讲,这使您对所有问题的答案都依赖于实现。当然,实际上,有一个堆栈(每个goroutine!)和一个堆,有些东西在堆栈上,有些东西在堆栈上。在某些情况下,编译器遵循严格的规则(例如“

new
始终在堆上分配”),而在其他情况下,编译器执行“转义分析”来确定对象是否可以存在于堆栈中,或者是否必须在堆中进行分配。

在示例2中,转义分析将显示指向结构转义的指针,因此编译器将不得不分配该结构。我认为,在这种情况下,Go的当前实现遵循严格的规则,即,如果地址从结构的任何部分获取,则结构将进入堆。

对于问题3,我们可能会对术语感到困惑。Go中的所有内容都是按值传递的,没有按引用传递的。在这里,您将返回一个指针值。指针的意义是什么?考虑对示例的以下修改:

type MyStructType struct{}func myFunction1() (*MyStructType, error) {    var chunk *MyStructType = new(MyStructType)    // ...    return chunk, nil}func myFunction2() (MyStructType, error) {    var chunk MyStructType    // ...    return chunk, nil}type bigStruct struct {    lots [1e6]float64}func myFunction3() (bigStruct, error) {    var chunk bigStruct    // ...    return chunk, nil}

我修改了myFunction2以返回结构而不是结构的地址。现在比较myFunction1和myFunction2的程序集输出,

--- prog list "myFunction1" ---0000 (s.go:5) TEXT    myFunction1+0(SB),-240001 (s.go:6) MOVQ    $type."".MyStructType+0(SB),(SP)0002 (s.go:6) CALL    ,runtime.new+0(SB)0003 (s.go:6) MOVQ    8(SP),AX0004 (s.go:8) MOVQ    AX,.noname+0(FP)0005 (s.go:8) MOVQ    
myStructType。对runtime.new的调用已消失,在某些情况下这将是一件好事。等等,这是myFunction3,
,.noname+8(FP)0006 (s.go:8) MOVQ
--- prog list "myFunction3" ---0016 (s.go:21) TEXT    myFunction3+0(SB),00000-80000160017 (s.go:22) LEAQ    chunk+-8000000(SP),DI0018 (s.go:22) MOVQ    ,AX0019 (s.go:22) MOVQ    00000,CX0020 (s.go:22) REP     ,0021 (s.go:22) STOSQ   ,0022 (s.go:24) LEAQ    chunk+-8000000(SP),SI0023 (s.go:24) LEAQ    .noname+0(FP),DI0024 (s.go:24) MOVQ    00000,CX0025 (s.go:24) REP     ,0026 (s.go:24) MOVSQ   ,0027 (s.go:24) MOVQ    ,.noname+8000000(FP)0028 (s.go:24) MOVQ    ,.noname+8000008(FP)0029 (s.go:24) RET     ,
,.noname+16(FP)0007 (s.go:8) RET ,--- prog list "myFunction2" ---0008 (s.go:11) TEXT myFunction2+0(SB),-160009 (s.go:12) LEAQ chunk+0(SP),DI0010 (s.go:12) MOVQ ,AX0011 (s.go:14) LEAQ .noname+0(FP),BX0012 (s.go:14) LEAQ chunk+0(SP),BX0013 (s.go:14) MOVQ ,.noname+0(FP)0014 (s.go:14) MOVQ [+++],.noname+8(FP)0015 (s.go:14) RET ,

不必担心这里的myFunction1输出与peterSO的(出色)答案不同。我们显然正在运行不同的编译器。否则,请参见我修改了myFunction2以返回myStructType而不是*[+++]

[+++]

仍然没有调用runtime.new,是的,它确实可以按值返回8MB对象。它有效,但是您通常不希望这样做。这里的指针指向是避免推送约8MB的对象。



)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 13, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

Go中结构堆栈vs堆分配,以及它们与垃圾回收的关系

值得注意的是,在语言规范中,“ stack”和“ heap”一词没有出现。您的问题用“ …在堆栈上声明”和“
…在堆栈上声明”来表述,但请注意,Go声明语法对堆栈或堆没有任何说明。

从技术上讲,这使您对所有问题的答案都依赖于实现。当然,实际上,有一个堆栈(每个goroutine!)和一个堆,有些东西在堆栈上,有些东西在堆栈上。在某些情况下,编译器遵循严格的规则(例如“

new
始终在堆上分配”),而在其他情况下,编译器执行“转义分析”来确定对象是否可以存在于堆栈中,或者是否必须在堆中进行分配。

在示例2中,转义分析将显示指向结构转义的指针,因此编译器将不得不分配该结构。我认为,在这种情况下,Go的当前实现遵循严格的规则,即,如果地址从结构的任何部分获取,则结构将进入堆。

对于问题3,我们可能会对术语感到困惑。Go中的所有内容都是按值传递的,没有按引用传递的。在这里,您将返回一个指针值。指针的意义是什么?考虑对示例的以下修改:

type MyStructType struct{}func myFunction1() (*MyStructType, error) {    var chunk *MyStructType = new(MyStructType)    // ...    return chunk, nil}func myFunction2() (MyStructType, error) {    var chunk MyStructType    // ...    return chunk, nil}type bigStruct struct {    lots [1e6]float64}func myFunction3() (bigStruct, error) {    var chunk bigStruct    // ...    return chunk, nil}

我修改了myFunction2以返回结构而不是结构的地址。现在比较myFunction1和myFunction2的程序集输出,

--- prog list "myFunction1" ---0000 (s.go:5) TEXT    myFunction1+0(SB),-240001 (s.go:6) MOVQ    $type."".MyStructType+0(SB),(SP)0002 (s.go:6) CALL    ,runtime.new+0(SB)0003 (s.go:6) MOVQ    8(SP),AX0004 (s.go:8) MOVQ    AX,.noname+0(FP)0005 (s.go:8) MOVQ    
myStructType。对runtime.new的调用已消失,在某些情况下这将是一件好事。等等,这是myFunction3,
,.noname+8(FP)0006 (s.go:8) MOVQ
--- prog list "myFunction3" ---0016 (s.go:21) TEXT    myFunction3+0(SB),00000-80000160017 (s.go:22) LEAQ    chunk+-8000000(SP),DI0018 (s.go:22) MOVQ    ,AX0019 (s.go:22) MOVQ    00000,CX0020 (s.go:22) REP     ,0021 (s.go:22) STOSQ   ,0022 (s.go:24) LEAQ    chunk+-8000000(SP),SI0023 (s.go:24) LEAQ    .noname+0(FP),DI0024 (s.go:24) MOVQ    00000,CX0025 (s.go:24) REP     ,0026 (s.go:24) MOVSQ   ,0027 (s.go:24) MOVQ    ,.noname+8000000(FP)0028 (s.go:24) MOVQ    ,.noname+8000008(FP)0029 (s.go:24) RET     ,
,.noname+16(FP)0007 (s.go:8) RET ,--- prog list "myFunction2" ---0008 (s.go:11) TEXT myFunction2+0(SB),-160009 (s.go:12) LEAQ chunk+0(SP),DI0010 (s.go:12) MOVQ ,AX0011 (s.go:14) LEAQ .noname+0(FP),BX0012 (s.go:14) LEAQ chunk+0(SP),BX0013 (s.go:14) MOVQ ,.noname+0(FP)0014 (s.go:14) MOVQ ,.noname+8(FP)0015 (s.go:14) RET ,

不必担心这里的myFunction1输出与peterSO的(出色)答案不同。我们显然正在运行不同的编译器。否则,请参见我修改了myFunction2以返回myStructType而不是*[+++]

[+++]

仍然没有调用runtime.new,是的,它确实可以按值返回8MB对象。它有效,但是您通常不希望这样做。这里的指针指向是避免推送约8MB的对象。



)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 14, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

Go中结构堆栈vs堆分配,以及它们与垃圾回收的关系

值得注意的是,在语言规范中,“ stack”和“ heap”一词没有出现。您的问题用“ …在堆栈上声明”和“
…在堆栈上声明”来表述,但请注意,Go声明语法对堆栈或堆没有任何说明。

从技术上讲,这使您对所有问题的答案都依赖于实现。当然,实际上,有一个堆栈(每个goroutine!)和一个堆,有些东西在堆栈上,有些东西在堆栈上。在某些情况下,编译器遵循严格的规则(例如“

new
始终在堆上分配”),而在其他情况下,编译器执行“转义分析”来确定对象是否可以存在于堆栈中,或者是否必须在堆中进行分配。

在示例2中,转义分析将显示指向结构转义的指针,因此编译器将不得不分配该结构。我认为,在这种情况下,Go的当前实现遵循严格的规则,即,如果地址从结构的任何部分获取,则结构将进入堆。

对于问题3,我们可能会对术语感到困惑。Go中的所有内容都是按值传递的,没有按引用传递的。在这里,您将返回一个指针值。指针的意义是什么?考虑对示例的以下修改:

type MyStructType struct{}func myFunction1() (*MyStructType, error) {    var chunk *MyStructType = new(MyStructType)    // ...    return chunk, nil}func myFunction2() (MyStructType, error) {    var chunk MyStructType    // ...    return chunk, nil}type bigStruct struct {    lots [1e6]float64}func myFunction3() (bigStruct, error) {    var chunk bigStruct    // ...    return chunk, nil}

我修改了myFunction2以返回结构而不是结构的地址。现在比较myFunction1和myFunction2的程序集输出,

--- prog list "myFunction1" ---0000 (s.go:5) TEXT    myFunction1+0(SB),-240001 (s.go:6) MOVQ    $type."".MyStructType+0(SB),(SP)0002 (s.go:6) CALL    ,runtime.new+0(SB)0003 (s.go:6) MOVQ    8(SP),AX0004 (s.go:8) MOVQ    AX,.noname+0(FP)0005 (s.go:8) MOVQ    
myStructType。对runtime.new的调用已消失,在某些情况下这将是一件好事。等等,这是myFunction3,
,.noname+8(FP)0006 (s.go:8) MOVQ
--- prog list "myFunction3" ---0016 (s.go:21) TEXT    myFunction3+0(SB),00000-80000160017 (s.go:22) LEAQ    chunk+-8000000(SP),DI0018 (s.go:22) MOVQ    ,AX0019 (s.go:22) MOVQ    00000,CX0020 (s.go:22) REP     ,0021 (s.go:22) STOSQ   ,0022 (s.go:24) LEAQ    chunk+-8000000(SP),SI0023 (s.go:24) LEAQ    .noname+0(FP),DI0024 (s.go:24) MOVQ    00000,CX0025 (s.go:24) REP     ,0026 (s.go:24) MOVSQ   ,0027 (s.go:24) MOVQ    ,.noname+8000000(FP)0028 (s.go:24) MOVQ    ,.noname+8000008(FP)0029 (s.go:24) RET     ,
,.noname+16(FP)0007 (s.go:8) RET ,--- prog list "myFunction2" ---0008 (s.go:11) TEXT myFunction2+0(SB),-160009 (s.go:12) LEAQ chunk+0(SP),DI0010 (s.go:12) MOVQ ,AX0011 (s.go:14) LEAQ .noname+0(FP),BX0012 (s.go:14) LEAQ chunk+0(SP),BX0013 (s.go:14) MOVQ ,.noname+0(FP)0014 (s.go:14) MOVQ ,.noname+8(FP)0015 (s.go:14) RET ,

不必担心这里的myFunction1输出与peterSO的(出色)答案不同。我们显然正在运行不同的编译器。否则,请参见我修改了myFunction2以返回myStructType而不是*

[+++]

仍然没有调用runtime.new,是的,它确实可以按值返回8MB对象。它有效,但是您通常不希望这样做。这里的指针指向是避免推送约8MB的对象。



)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Go中结构的堆栈vs堆分配,以及它们与垃圾回收的关系_随笔_内存溢出

Go中结构的堆栈vs堆分配,以及它们与垃圾回收的关系

Go中结构的堆栈vs堆分配,以及它们与垃圾回收的关系,第1张

Go中结构堆栈vs堆分配,以及它们与垃圾回收的关系

值得注意的是,在语言规范中,“ stack”和“ heap”一词没有出现。您的问题用“ …在堆栈上声明”和“
…在堆栈上声明”来表述,但请注意,Go声明语法对堆栈或堆没有任何说明。

从技术上讲,这使您对所有问题的答案都依赖于实现。当然,实际上,有一个堆栈(每个goroutine!)和一个堆,有些东西在堆栈上,有些东西在堆栈上。在某些情况下,编译器遵循严格的规则(例如“

new
始终在堆上分配”),而在其他情况下,编译器执行“转义分析”来确定对象是否可以存在于堆栈中,或者是否必须在堆中进行分配。

在示例2中,转义分析将显示指向结构转义的指针,因此编译器将不得不分配该结构。我认为,在这种情况下,Go的当前实现遵循严格的规则,即,如果地址从结构的任何部分获取,则结构将进入堆。

对于问题3,我们可能会对术语感到困惑。Go中的所有内容都是按值传递的,没有按引用传递的。在这里,您将返回一个指针值。指针的意义是什么?考虑对示例的以下修改:

type MyStructType struct{}func myFunction1() (*MyStructType, error) {    var chunk *MyStructType = new(MyStructType)    // ...    return chunk, nil}func myFunction2() (MyStructType, error) {    var chunk MyStructType    // ...    return chunk, nil}type bigStruct struct {    lots [1e6]float64}func myFunction3() (bigStruct, error) {    var chunk bigStruct    // ...    return chunk, nil}

我修改了myFunction2以返回结构而不是结构的地址。现在比较myFunction1和myFunction2的程序集输出,

--- prog list "myFunction1" ---0000 (s.go:5) TEXT    myFunction1+0(SB),-240001 (s.go:6) MOVQ    $type."".MyStructType+0(SB),(SP)0002 (s.go:6) CALL    ,runtime.new+0(SB)0003 (s.go:6) MOVQ    8(SP),AX0004 (s.go:8) MOVQ    AX,.noname+0(FP)0005 (s.go:8) MOVQ    
myStructType。对runtime.new的调用已消失,在某些情况下这将是一件好事。等等,这是myFunction3,
,.noname+8(FP)0006 (s.go:8) MOVQ
--- prog list "myFunction3" ---0016 (s.go:21) TEXT    myFunction3+0(SB),00000-80000160017 (s.go:22) LEAQ    chunk+-8000000(SP),DI0018 (s.go:22) MOVQ    ,AX0019 (s.go:22) MOVQ    00000,CX0020 (s.go:22) REP     ,0021 (s.go:22) STOSQ   ,0022 (s.go:24) LEAQ    chunk+-8000000(SP),SI0023 (s.go:24) LEAQ    .noname+0(FP),DI0024 (s.go:24) MOVQ    00000,CX0025 (s.go:24) REP     ,0026 (s.go:24) MOVSQ   ,0027 (s.go:24) MOVQ    ,.noname+8000000(FP)0028 (s.go:24) MOVQ    ,.noname+8000008(FP)0029 (s.go:24) RET     ,
,.noname+16(FP)0007 (s.go:8) RET ,--- prog list "myFunction2" ---0008 (s.go:11) TEXT myFunction2+0(SB),-160009 (s.go:12) LEAQ chunk+0(SP),DI0010 (s.go:12) MOVQ ,AX0011 (s.go:14) LEAQ .noname+0(FP),BX0012 (s.go:14) LEAQ chunk+0(SP),BX0013 (s.go:14) MOVQ ,.noname+0(FP)0014 (s.go:14) MOVQ ,.noname+8(FP)0015 (s.go:14) RET ,

不必担心这里的myFunction1输出与peterSO的(出色)答案不同。我们显然正在运行不同的编译器。否则,请参见我修改了myFunction2以返回myStructType而不是*

仍然没有调用runtime.new,是的,它确实可以按值返回8MB对象。它有效,但是您通常不希望这样做。这里的指针指向是避免推送约8MB的对象。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5170015.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-18
下一篇 2022-11-18

发表评论

登录后才能评论

评论列表(0条)

保存