Вывод: len: 3, cap: 999900, затем «Первый элемент: 100». Подслайс удерживает весь исходный массив, поэтому runtime.GC не освобождает его.
package main
Вывод: len: 3, cap: 999900, затем «Первый элемент: 100». Подслайс удерживает весь исходный массив, поэтому runtime.GC не освобождает его.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
package main
import ( "fmt" "runtime" )
func getSubSlice() []int { // Инициализируем большой срез bigSlice := make([]int, 1_000_000) for i := range bigSlice { bigSlice[i] = i } // Возвращаем подрез из 3 элементов return bigSlice[100:103] }
func main() { res := getSubSlice()
// Проверяем len и cap fmt.Printf("len: %d, cap: %d\n", len(res), cap(res))
// Вызываем сборщик мусора runtime.GC()
// Будет ли очищен массив на 1 000 000 элементов? fmt.Println("Первый элемент:", res[0]) }
Вопрос: Что выведет данный код и почему? Какая проблема с памятью здесь скрыта и как её исправить?
Ответ
Вывод: len: 3, cap: 999900, затем «Первый элемент: 100». Подслайс удерживает весь исходный массив, поэтому runtime.GC не освобождает его.
Скопируйте только нужные элементы перед возвратом:
result := make([]int, 3)
copy(result, bigSlice[100:103])
return result
Теперь результат имеет собственный небольшой массив. Полное выражение bigSlice[100:103:103] уменьшило бы только доступную capacity, но не убрало ссылку на большой backing array. Достижимые данные сборщик освобождать не может.