需要帮助以了解GoLang中的垃圾收集

时间:2019-07-24 22:55:12

标签: go garbage-collection unsafe-pointers

我对GoLang的垃圾收集器有些困惑。

考虑以下代码,在其中我为T型实现阅读器接口。

master_df = pd.DataFrame({
    'col1': ['M', 'F', 'F', 'M'],
    'col2': [0, 1, 2, 3],
    'col3': ['X', 'Z', 'Z', 'X'],
    'col4': [2021, 2022, 2023, 2024],
    'col5': [.632, .232, .37, .5005]
})

其中的阅读器函数中,我将使用master_df将数据转换为MyDataType,该数据将指向使用反射模块创建的切片(这比较复杂,但出于示例的考虑,这应该足够了)< / p>

DataFrame

如果我要以其他功能读取数据

type T struct {
   header Header
   data   []*MyDataType
}

func (t *T) Read(p []byte) (int, error) {
    t.Header = *(*Header) (t.readFileHeader(p))
    t.Data = *(*[]*MyDataType) (t.readFileData(p))
}

现在我很困惑,如果可能的话,GC将在退出unsafe.Pointer函数之后从文件中释放已加载的数据。否则将释放func (t *T) readFileData(data []byte, idx int, ...) unsafe.Pointer { ... return unsafe.Pointer(&reflect.SliceHeader{Data : uintptr(unsafe.Pointer(&data[idx])), ...}) } 之后释放数据。

2 个答案:

答案 0 :(得分:1)

要了解GC可能对您的变量执行的操作,首先您需要知道Go如何以及​​在何处分配变量。这是有关escape analysis的很好的读物,这是Go编译器如何确定在堆栈或堆之间分配内存的位置。

长话短说,只有当Go程序未引用GC时,GC才会释放内存。

在您的示例中,data, _ := ioutil.ReadFile(filename)对加载数据的引用最终传递给t.Data = *(*[]*MyDataType) (t.readFileData(p))。因此,只要也引用了(t *T)结构,就将引用它们。据我从您的代码中看到的那样,加载的数据将与(t *T)一起进行垃圾收集。

答案 1 :(得分:-2)

根据reflect docs,我必须保留指向data *[]byte的单独指针,以避免垃圾回收。因此,解决方案是将referencePtr添加到

type T struct {
   header              Header
   data                   []*MyDataType
   referencePtr      *[]byte
}

它将指向Read函数中的我的数据

func (t *T) Read(p []byte) (int, error) {
    t.referencePtr = &p
    t.Header = *(*Header) (t.readFileHeader(p))
    t.Data = *(*[]*MyDataType) (t.readFileData(p))
}

还是这是不必要的?