这会导致Go语言中的内存泄漏吗?

huangapple go评论75阅读模式
英文:

Will this cause a memory leak in Go?

问题

在下面的代码中,我有两个结构体类型:ObjectDefinitionfieldDefinition,它们都在同一个包中。fieldDefinition结构体应该只能通过ObjectDefinition上的一个方法来创建,以防止孤立的字段(所讨论的系统将是一个可扩展的CRM)。

AddReferenceField方法应该创建一个新的fieldDefinition,在其上设置一些变量,将其添加到父结构体的*fieldDefinition切片中,并且还应该返回指向它的指针,以便程序员可以轻松地进一步操作该字段,而无需从切片中查找和检索它。

type ObjectDefinition struct {
    myId        id.ID
    orgId       id.ID
    apiName     string
    label       string
    pluralLabel string
    description string
    helpText    string
    fields      map[id.ID]*fieldDefinition
    newFields   []*fieldDefinition
    systemFields
}

/*
AddReferenceField将引用类型字段添加到未提交字段列表中,并返回指向它的指针。如果给定的参数中有任何无效参数,此函数将返回nil指针和错误。
*/
func (o *ObjectDefinition) AddReferenceField(name, label string, refObj id.ID, reparentable bool, delCon deleteConstraint) (*fieldDefinition, error) {

    //TODO - investigate this as a possible source of memory leakage. Creating a pointer, adding that pointer to a slice, then returning the same pointer.
    nrf := new(fieldDefinition)
    nrf.fieldType = FT_REFERENCE

    if err := nrf.SetName(name); err != nil {
        return nil, err
    }

    if err := nrf.SetLabel(label); err != nil {
        return nil, err
    }

    if err := nrf.SetReferenceObjectId(refObj); err != nil {
        return nil, err
    }

    if err := nrf.SetReparentable(reparentable); err != nil {
        return nil, err
    }

    if err := nrf.SetDeleteConstraint(delCon); err != nil {
        return nil, err
    }

    o.newFields = append(o.newFields, nrf)
    return nrf, nil

}

我没有包含完整的fieldDefinition代码,因为它并不是非常相关且相当庞大,但是从主程序循环中使用它的示例可能是:

var od ObjectDefinition
newId := id.Generate()
newField, newFieldErr := od.AddReferenceField("example", "Example", newId, false, DC_SETNULL)

newField.SetSomethingElse(true)

所以现在newField是指向fieldDefinition的指针,但是同一个指针已经被添加到了od的一个切片中。这里是否存在内存泄漏的潜在问题?

英文:

In the following code I have two struct types: ObjectDefinition and fieldDefinition both in the same package. fieldDefinition structs should only be created via a method on ObjectDefinition to prevent orphaned fields (the system in question will be an extensible CRM).

The AddReferenceField method should create a new fieldDefintion, set some variables on it, add it to the parent struct's slice of *fieldDefinition and then also return the pointer to it to allow the programmer to easily manipulate the field further without having to find and retrieve it from the slice.

type ObjectDefinition struct {
	myId        id.ID
	orgId       id.ID
	apiName     string
	label       string
	pluralLabel string
	description string
	helpText    string
	fields      map[id.ID]*fieldDefinition
	newFields   []*fieldDefinition
	systemFields
}

/*
AddReferenceField adds a reference type field to the list of uncommitted fields
with the given parameters and returns a pointer to it. This function will return
a nil pointer and an error if any of the given parameters were invalid.
*/
func (o *ObjectDefinition) AddReferenceField(name, label string, refObj id.ID, reparentable bool, delCon deleteConstraint) (*fieldDefinition, error) {

	//TODO - investigate this as a possible source of memory leakage. Creating a pointer, adding that pointer to a slice, then returning the same pointer.
	nrf := new(fieldDefinition)
	nrf.fieldType = FT_REFERENCE

	if err := nrf.SetName(name); err != nil {
		return nil, err
	}

	if err := nrf.SetLabel(label); err != nil {
		return nil, err
	}

	if err := nrf.SetReferenceObjectId(refObj); err != nil {
		return nil, err
	}

	if err := nrf.SetReparentable(reparentable); err != nil {
		return nil, err
	}

	if err := nrf.SetDeleteConstraint(delCon); err != nil {
		return nil, err
	}

	o.newFields = append(o.newFields, nrf)
	return nrf, nil

}

I haven't included the full fieldDefinition code because it's not really relevant and it's quite bulky, but an example of this being used from the main program loop would be:

var od ObjectDefinition
newId := id.Generate()
newField, newFieldErr := od.AddReferenceField("example", "Example", newId, false, DC_SETNULL)

newField.SetSomethingElse(true)

So now newField is a pointer to fieldDefinition, but the same pointer has been added to a slice on od. Is there a potential for memory leakage here?

答案1

得分: 1

Go是一种垃圾回收语言。回应评论中其他人的观点,这并不会导致内存泄漏。虽然od持有指向新创建的fieldDefinition的指针,但是fieldDefinition将会保留在堆中。当od超出作用域并被销毁时,所有它所指向的fieldDefinition也将变得适合进行垃圾回收,前提是没有其他活动对象持有对它们的指针。

英文:

Go is a garbage collected language. Echoing what people in the comments have said, this does not cause a memory leak. While od holds the pointer to the newly created fieldDefinition, that fieldDefinition will stay in the heap. When od goes out of scope and is destroyed, all the fieldDefinitions it's pointing to will also become eligible for garbage collection, provided that nothing live is holding a pointer to them.

huangapple
  • 本文由 发表于 2015年9月3日 23:04:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/32379248.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定