Memory leak in golang slice2019 Community Moderator ElectionDoes go garbage collect parts of slices?Understanding slice notationJavaScript chop/slice/trim off last character in stringFastest way to duplicate an array in JavaScript - slice vs. 'for' loopContains method for a sliceConcatenate two slices in GoThe last element of a sliceCorrect way to initialize empty sliceSlices in golang do not allocate any memory?Why can not I duplicate a slice with `copy()` in Golang?nil slices vs non-nil slices vs empty slices in Go language

Can a druid choose the size of its wild shape beast?

If I can solve Sudoku can I solve Travelling Salesman Problem(TSP)? If yes, how?

How can I track script which gives me "command not found" right after the login?

Did Ender ever learn that he killed Stilson and/or Bonzo?

Look at your watch and tell me what time is it. vs Look at your watch and tell me what time it is

Professor being mistaken for a grad student

Are there verbs that are neither telic, or atelic?

Welcoming 2019 Pi day: How to draw the letter π?

Are all passive ability checks floors for active ability checks?

What are substitutions for coconut in curry?

What are the naunces between the use of 訊く instead of 聞く in the following sentence?

Can I use USB data pins as power source

How to explain that I do not want to visit a country due to personal safety concern?

Hacking a Safe Lock after 3 tries

Most cost effective thermostat setting: consistent temperature vs. lowest temperature possible

Is it normal that my co-workers at a fitness company criticize my food choices?

Could the Saturn V actually have launched astronauts around Venus?

What options are left, if Britain cannot decide?

How to terminate ping <dest> &

How to deal with a cynical class?

In a future war, an old lady is trying to raise a boy but one of the weapons has made everyone deaf

Co-worker team leader wants to inject his friend's awful software into our development. What should I say to our common boss?

Use of undefined constant bloginfo

Sailing the cryptic seas



Memory leak in golang slice



2019 Community Moderator ElectionDoes go garbage collect parts of slices?Understanding slice notationJavaScript chop/slice/trim off last character in stringFastest way to duplicate an array in JavaScript - slice vs. 'for' loopContains method for a sliceConcatenate two slices in GoThe last element of a sliceCorrect way to initialize empty sliceSlices in golang do not allocate any memory?Why can not I duplicate a slice with `copy()` in Golang?nil slices vs non-nil slices vs empty slices in Go language










3















I just started learning go, while going through slice tricks, couple of points are very confusing. can any one help me to clarify.



To cut elements in slice its given



Approach 1:



a = append(a[:i], a[j:]...)


but there is a note given that it may cause to memory leaks if pointers are used and recommended way is



Approach 2:



copy(a[i:], a[j:])
for k, n := len(a)-j+i, len(a); k < n; k++
a[k] = nil // or the zero value of T

a = a[:len(a)-j+i]


Can any one help me understand how memory leaks happen.
I understood sub slice will be backed by the main array. My thought is irrespective of pointer or not we have to follow approach 2 always.



update after @icza and @Volker answer..



Lets say you have a struct



type Books struct 
title string
author string


var Book1 Books
var Book2 Books

/* book 1 specification */
Book1.title = "Go Programming"
Book1.author = "Mahesh Kumar"

Book2.title = "Go Programming"
Book2.author = "Mahesh Kumar"

var bkSlice = []BooksBook1, Book2
var bkprtSlice = []*Books&Book1, &Book2


now doing



bkSlice = bkSlice[:1]


bkSlice still holds the Book2 in backing array which is still in memory and is not required to be.
so do we need to do



bkSlice[1] = Books


so that it will be GCed. I understood pointers have to be nil-ed as the slice will hold unnecessary references to the objects outside backing array.










share|improve this question



















  • 1





    This is not a memory leak in the traditional sense: Once the backing array gets garbage collected because no slice reference it any longer all memory is claimed and no leak happens. It is just that the memory is claimed only after all slices are gone. With the recommended code the memory pointed to can be claimed earlier.

    – Volker
    Mar 7 at 14:17











  • See: Does go garbage collect parts of slices?

    – icza
    Mar 7 at 14:28











  • @icza i saw this answer, even in that is says if we use pointers it may leak memory..my understanding is even if we use direct object this will cause memory issues. why it causes specifically for pointers.

    – Samarendra
    Mar 7 at 14:36











  • @Volker I agree with you, but why it is specifically mentioned in case of pointer. it should be the case weather its pointers or not?

    – Samarendra
    Mar 7 at 14:37











  • Again: There is never any memory leak. It is about allowing to claim memory earlier. This early claim can be done is the slice contains pointers (or slices or maps or channels) which can be nil-ed in the backing array before slicing. If you have a slice of ints the ints cannot be GCed as they are part of the backing array.

    – Volker
    Mar 7 at 15:01















3















I just started learning go, while going through slice tricks, couple of points are very confusing. can any one help me to clarify.



To cut elements in slice its given



Approach 1:



a = append(a[:i], a[j:]...)


but there is a note given that it may cause to memory leaks if pointers are used and recommended way is



Approach 2:



copy(a[i:], a[j:])
for k, n := len(a)-j+i, len(a); k < n; k++
a[k] = nil // or the zero value of T

a = a[:len(a)-j+i]


Can any one help me understand how memory leaks happen.
I understood sub slice will be backed by the main array. My thought is irrespective of pointer or not we have to follow approach 2 always.



update after @icza and @Volker answer..



Lets say you have a struct



type Books struct 
title string
author string


var Book1 Books
var Book2 Books

/* book 1 specification */
Book1.title = "Go Programming"
Book1.author = "Mahesh Kumar"

Book2.title = "Go Programming"
Book2.author = "Mahesh Kumar"

var bkSlice = []BooksBook1, Book2
var bkprtSlice = []*Books&Book1, &Book2


now doing



bkSlice = bkSlice[:1]


bkSlice still holds the Book2 in backing array which is still in memory and is not required to be.
so do we need to do



bkSlice[1] = Books


so that it will be GCed. I understood pointers have to be nil-ed as the slice will hold unnecessary references to the objects outside backing array.










share|improve this question



















  • 1





    This is not a memory leak in the traditional sense: Once the backing array gets garbage collected because no slice reference it any longer all memory is claimed and no leak happens. It is just that the memory is claimed only after all slices are gone. With the recommended code the memory pointed to can be claimed earlier.

    – Volker
    Mar 7 at 14:17











  • See: Does go garbage collect parts of slices?

    – icza
    Mar 7 at 14:28











  • @icza i saw this answer, even in that is says if we use pointers it may leak memory..my understanding is even if we use direct object this will cause memory issues. why it causes specifically for pointers.

    – Samarendra
    Mar 7 at 14:36











  • @Volker I agree with you, but why it is specifically mentioned in case of pointer. it should be the case weather its pointers or not?

    – Samarendra
    Mar 7 at 14:37











  • Again: There is never any memory leak. It is about allowing to claim memory earlier. This early claim can be done is the slice contains pointers (or slices or maps or channels) which can be nil-ed in the backing array before slicing. If you have a slice of ints the ints cannot be GCed as they are part of the backing array.

    – Volker
    Mar 7 at 15:01













3












3








3








I just started learning go, while going through slice tricks, couple of points are very confusing. can any one help me to clarify.



To cut elements in slice its given



Approach 1:



a = append(a[:i], a[j:]...)


but there is a note given that it may cause to memory leaks if pointers are used and recommended way is



Approach 2:



copy(a[i:], a[j:])
for k, n := len(a)-j+i, len(a); k < n; k++
a[k] = nil // or the zero value of T

a = a[:len(a)-j+i]


Can any one help me understand how memory leaks happen.
I understood sub slice will be backed by the main array. My thought is irrespective of pointer or not we have to follow approach 2 always.



update after @icza and @Volker answer..



Lets say you have a struct



type Books struct 
title string
author string


var Book1 Books
var Book2 Books

/* book 1 specification */
Book1.title = "Go Programming"
Book1.author = "Mahesh Kumar"

Book2.title = "Go Programming"
Book2.author = "Mahesh Kumar"

var bkSlice = []BooksBook1, Book2
var bkprtSlice = []*Books&Book1, &Book2


now doing



bkSlice = bkSlice[:1]


bkSlice still holds the Book2 in backing array which is still in memory and is not required to be.
so do we need to do



bkSlice[1] = Books


so that it will be GCed. I understood pointers have to be nil-ed as the slice will hold unnecessary references to the objects outside backing array.










share|improve this question
















I just started learning go, while going through slice tricks, couple of points are very confusing. can any one help me to clarify.



To cut elements in slice its given



Approach 1:



a = append(a[:i], a[j:]...)


but there is a note given that it may cause to memory leaks if pointers are used and recommended way is



Approach 2:



copy(a[i:], a[j:])
for k, n := len(a)-j+i, len(a); k < n; k++
a[k] = nil // or the zero value of T

a = a[:len(a)-j+i]


Can any one help me understand how memory leaks happen.
I understood sub slice will be backed by the main array. My thought is irrespective of pointer or not we have to follow approach 2 always.



update after @icza and @Volker answer..



Lets say you have a struct



type Books struct 
title string
author string


var Book1 Books
var Book2 Books

/* book 1 specification */
Book1.title = "Go Programming"
Book1.author = "Mahesh Kumar"

Book2.title = "Go Programming"
Book2.author = "Mahesh Kumar"

var bkSlice = []BooksBook1, Book2
var bkprtSlice = []*Books&Book1, &Book2


now doing



bkSlice = bkSlice[:1]


bkSlice still holds the Book2 in backing array which is still in memory and is not required to be.
so do we need to do



bkSlice[1] = Books


so that it will be GCed. I understood pointers have to be nil-ed as the slice will hold unnecessary references to the objects outside backing array.







pointers go copy append slice






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 7 at 15:39







Samarendra

















asked Mar 7 at 13:50









SamarendraSamarendra

326310




326310







  • 1





    This is not a memory leak in the traditional sense: Once the backing array gets garbage collected because no slice reference it any longer all memory is claimed and no leak happens. It is just that the memory is claimed only after all slices are gone. With the recommended code the memory pointed to can be claimed earlier.

    – Volker
    Mar 7 at 14:17











  • See: Does go garbage collect parts of slices?

    – icza
    Mar 7 at 14:28











  • @icza i saw this answer, even in that is says if we use pointers it may leak memory..my understanding is even if we use direct object this will cause memory issues. why it causes specifically for pointers.

    – Samarendra
    Mar 7 at 14:36











  • @Volker I agree with you, but why it is specifically mentioned in case of pointer. it should be the case weather its pointers or not?

    – Samarendra
    Mar 7 at 14:37











  • Again: There is never any memory leak. It is about allowing to claim memory earlier. This early claim can be done is the slice contains pointers (or slices or maps or channels) which can be nil-ed in the backing array before slicing. If you have a slice of ints the ints cannot be GCed as they are part of the backing array.

    – Volker
    Mar 7 at 15:01












  • 1





    This is not a memory leak in the traditional sense: Once the backing array gets garbage collected because no slice reference it any longer all memory is claimed and no leak happens. It is just that the memory is claimed only after all slices are gone. With the recommended code the memory pointed to can be claimed earlier.

    – Volker
    Mar 7 at 14:17











  • See: Does go garbage collect parts of slices?

    – icza
    Mar 7 at 14:28











  • @icza i saw this answer, even in that is says if we use pointers it may leak memory..my understanding is even if we use direct object this will cause memory issues. why it causes specifically for pointers.

    – Samarendra
    Mar 7 at 14:36











  • @Volker I agree with you, but why it is specifically mentioned in case of pointer. it should be the case weather its pointers or not?

    – Samarendra
    Mar 7 at 14:37











  • Again: There is never any memory leak. It is about allowing to claim memory earlier. This early claim can be done is the slice contains pointers (or slices or maps or channels) which can be nil-ed in the backing array before slicing. If you have a slice of ints the ints cannot be GCed as they are part of the backing array.

    – Volker
    Mar 7 at 15:01







1




1





This is not a memory leak in the traditional sense: Once the backing array gets garbage collected because no slice reference it any longer all memory is claimed and no leak happens. It is just that the memory is claimed only after all slices are gone. With the recommended code the memory pointed to can be claimed earlier.

– Volker
Mar 7 at 14:17





This is not a memory leak in the traditional sense: Once the backing array gets garbage collected because no slice reference it any longer all memory is claimed and no leak happens. It is just that the memory is claimed only after all slices are gone. With the recommended code the memory pointed to can be claimed earlier.

– Volker
Mar 7 at 14:17













See: Does go garbage collect parts of slices?

– icza
Mar 7 at 14:28





See: Does go garbage collect parts of slices?

– icza
Mar 7 at 14:28













@icza i saw this answer, even in that is says if we use pointers it may leak memory..my understanding is even if we use direct object this will cause memory issues. why it causes specifically for pointers.

– Samarendra
Mar 7 at 14:36





@icza i saw this answer, even in that is says if we use pointers it may leak memory..my understanding is even if we use direct object this will cause memory issues. why it causes specifically for pointers.

– Samarendra
Mar 7 at 14:36













@Volker I agree with you, but why it is specifically mentioned in case of pointer. it should be the case weather its pointers or not?

– Samarendra
Mar 7 at 14:37





@Volker I agree with you, but why it is specifically mentioned in case of pointer. it should be the case weather its pointers or not?

– Samarendra
Mar 7 at 14:37













Again: There is never any memory leak. It is about allowing to claim memory earlier. This early claim can be done is the slice contains pointers (or slices or maps or channels) which can be nil-ed in the backing array before slicing. If you have a slice of ints the ints cannot be GCed as they are part of the backing array.

– Volker
Mar 7 at 15:01





Again: There is never any memory leak. It is about allowing to claim memory earlier. This early claim can be done is the slice contains pointers (or slices or maps or channels) which can be nil-ed in the backing array before slicing. If you have a slice of ints the ints cannot be GCed as they are part of the backing array.

– Volker
Mar 7 at 15:01












1 Answer
1






active

oldest

votes


















2














Simplest can be demonstrated by a simple slice expression.



Let's start with a slice of *int pointers:



s := []*intnew(int), new(int)


This slice has a backing array with a length of 2, and it contains 2 non-nil pointers, pointing to allocated integers (outside of the backing array).



Now if we reslice this slice:



s = s[:1]


Length will become 1. The backing array (holding 2 pointers) is not touched, it sill holds 2 valid pointers. Even though we don't use the 2nd pointer now, since it is in memory (it is the backing array), the pointed object (which is a memory space for storing an int value) cannot be freed by the garbage collector.



The same thing happens if you "cut" multiple elements from the middle. If the original slice (and its backing array) was filled with non-nil pointers, and if you don't zero them (with nil), they will be kept in memory.



Why isn't this an issue with non-pointers?



Actually, this is an issue with all pointer and "header" types (like slices and strings), not just pointers.



If you would have a slice of type []int instead of []*int, then slicing it will just "hide" elements that are of int type which must stay in memory as part of the backing array regardless of if there's a slice that contains it or not. The elements are not references to objects stored outside of the array, while pointers refer to objects being outside of the array.



If the slice contains pointers and you nil them before the slicing operation, if there are no other references to the pointed objects (if the array was the only one holding the pointers), they can be freed, they will not be kept due to still having a slice (and thus the backing array).



Update:



When you have a slice of structs:



var bkSlice = []BooksBook1, Book2


If you slice it like:



bkSlice = bkSlice[:1]


Book2 will become unreachabe via bkSlice, but still will be in memory (as part of the backing array).



You can't nil it because nil is not a valid value for structs. You can however assign its zero value to it like this:



bkSlice[1] = Book
bkSlice = bkSlice[:1]


Note that a Books struct value will still be in memory, being the second element of the backing array, but that struct will be a zero value, and thus will not hold string references, thus the original book author and title strings can be garbage collected (if no one else references them; more precisely the byte slice referred from the string header).



The general rule is "recursive": You only need to zero elements that refer to memory located outside of the backing array. So if you have a slice of structs that only have e.g. int fields, you do not need to zero it, in fact it's just unnecessary extra work. If the struct has fields that are pointers, or slices, or e.g. other struct type that have pointers or slices etc., then you should zero it in order to remove the reference to the memory outside of the backing array.






share|improve this answer

























  • Thank you for the answer, I have updated the question, can you please check once.

    – Samarendra
    Mar 7 at 15:24











  • @Samarendra See edited answer.

    – icza
    Mar 7 at 15:28










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55045402%2fmemory-leak-in-golang-slice%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









2














Simplest can be demonstrated by a simple slice expression.



Let's start with a slice of *int pointers:



s := []*intnew(int), new(int)


This slice has a backing array with a length of 2, and it contains 2 non-nil pointers, pointing to allocated integers (outside of the backing array).



Now if we reslice this slice:



s = s[:1]


Length will become 1. The backing array (holding 2 pointers) is not touched, it sill holds 2 valid pointers. Even though we don't use the 2nd pointer now, since it is in memory (it is the backing array), the pointed object (which is a memory space for storing an int value) cannot be freed by the garbage collector.



The same thing happens if you "cut" multiple elements from the middle. If the original slice (and its backing array) was filled with non-nil pointers, and if you don't zero them (with nil), they will be kept in memory.



Why isn't this an issue with non-pointers?



Actually, this is an issue with all pointer and "header" types (like slices and strings), not just pointers.



If you would have a slice of type []int instead of []*int, then slicing it will just "hide" elements that are of int type which must stay in memory as part of the backing array regardless of if there's a slice that contains it or not. The elements are not references to objects stored outside of the array, while pointers refer to objects being outside of the array.



If the slice contains pointers and you nil them before the slicing operation, if there are no other references to the pointed objects (if the array was the only one holding the pointers), they can be freed, they will not be kept due to still having a slice (and thus the backing array).



Update:



When you have a slice of structs:



var bkSlice = []BooksBook1, Book2


If you slice it like:



bkSlice = bkSlice[:1]


Book2 will become unreachabe via bkSlice, but still will be in memory (as part of the backing array).



You can't nil it because nil is not a valid value for structs. You can however assign its zero value to it like this:



bkSlice[1] = Book
bkSlice = bkSlice[:1]


Note that a Books struct value will still be in memory, being the second element of the backing array, but that struct will be a zero value, and thus will not hold string references, thus the original book author and title strings can be garbage collected (if no one else references them; more precisely the byte slice referred from the string header).



The general rule is "recursive": You only need to zero elements that refer to memory located outside of the backing array. So if you have a slice of structs that only have e.g. int fields, you do not need to zero it, in fact it's just unnecessary extra work. If the struct has fields that are pointers, or slices, or e.g. other struct type that have pointers or slices etc., then you should zero it in order to remove the reference to the memory outside of the backing array.






share|improve this answer

























  • Thank you for the answer, I have updated the question, can you please check once.

    – Samarendra
    Mar 7 at 15:24











  • @Samarendra See edited answer.

    – icza
    Mar 7 at 15:28















2














Simplest can be demonstrated by a simple slice expression.



Let's start with a slice of *int pointers:



s := []*intnew(int), new(int)


This slice has a backing array with a length of 2, and it contains 2 non-nil pointers, pointing to allocated integers (outside of the backing array).



Now if we reslice this slice:



s = s[:1]


Length will become 1. The backing array (holding 2 pointers) is not touched, it sill holds 2 valid pointers. Even though we don't use the 2nd pointer now, since it is in memory (it is the backing array), the pointed object (which is a memory space for storing an int value) cannot be freed by the garbage collector.



The same thing happens if you "cut" multiple elements from the middle. If the original slice (and its backing array) was filled with non-nil pointers, and if you don't zero them (with nil), they will be kept in memory.



Why isn't this an issue with non-pointers?



Actually, this is an issue with all pointer and "header" types (like slices and strings), not just pointers.



If you would have a slice of type []int instead of []*int, then slicing it will just "hide" elements that are of int type which must stay in memory as part of the backing array regardless of if there's a slice that contains it or not. The elements are not references to objects stored outside of the array, while pointers refer to objects being outside of the array.



If the slice contains pointers and you nil them before the slicing operation, if there are no other references to the pointed objects (if the array was the only one holding the pointers), they can be freed, they will not be kept due to still having a slice (and thus the backing array).



Update:



When you have a slice of structs:



var bkSlice = []BooksBook1, Book2


If you slice it like:



bkSlice = bkSlice[:1]


Book2 will become unreachabe via bkSlice, but still will be in memory (as part of the backing array).



You can't nil it because nil is not a valid value for structs. You can however assign its zero value to it like this:



bkSlice[1] = Book
bkSlice = bkSlice[:1]


Note that a Books struct value will still be in memory, being the second element of the backing array, but that struct will be a zero value, and thus will not hold string references, thus the original book author and title strings can be garbage collected (if no one else references them; more precisely the byte slice referred from the string header).



The general rule is "recursive": You only need to zero elements that refer to memory located outside of the backing array. So if you have a slice of structs that only have e.g. int fields, you do not need to zero it, in fact it's just unnecessary extra work. If the struct has fields that are pointers, or slices, or e.g. other struct type that have pointers or slices etc., then you should zero it in order to remove the reference to the memory outside of the backing array.






share|improve this answer

























  • Thank you for the answer, I have updated the question, can you please check once.

    – Samarendra
    Mar 7 at 15:24











  • @Samarendra See edited answer.

    – icza
    Mar 7 at 15:28













2












2








2







Simplest can be demonstrated by a simple slice expression.



Let's start with a slice of *int pointers:



s := []*intnew(int), new(int)


This slice has a backing array with a length of 2, and it contains 2 non-nil pointers, pointing to allocated integers (outside of the backing array).



Now if we reslice this slice:



s = s[:1]


Length will become 1. The backing array (holding 2 pointers) is not touched, it sill holds 2 valid pointers. Even though we don't use the 2nd pointer now, since it is in memory (it is the backing array), the pointed object (which is a memory space for storing an int value) cannot be freed by the garbage collector.



The same thing happens if you "cut" multiple elements from the middle. If the original slice (and its backing array) was filled with non-nil pointers, and if you don't zero them (with nil), they will be kept in memory.



Why isn't this an issue with non-pointers?



Actually, this is an issue with all pointer and "header" types (like slices and strings), not just pointers.



If you would have a slice of type []int instead of []*int, then slicing it will just "hide" elements that are of int type which must stay in memory as part of the backing array regardless of if there's a slice that contains it or not. The elements are not references to objects stored outside of the array, while pointers refer to objects being outside of the array.



If the slice contains pointers and you nil them before the slicing operation, if there are no other references to the pointed objects (if the array was the only one holding the pointers), they can be freed, they will not be kept due to still having a slice (and thus the backing array).



Update:



When you have a slice of structs:



var bkSlice = []BooksBook1, Book2


If you slice it like:



bkSlice = bkSlice[:1]


Book2 will become unreachabe via bkSlice, but still will be in memory (as part of the backing array).



You can't nil it because nil is not a valid value for structs. You can however assign its zero value to it like this:



bkSlice[1] = Book
bkSlice = bkSlice[:1]


Note that a Books struct value will still be in memory, being the second element of the backing array, but that struct will be a zero value, and thus will not hold string references, thus the original book author and title strings can be garbage collected (if no one else references them; more precisely the byte slice referred from the string header).



The general rule is "recursive": You only need to zero elements that refer to memory located outside of the backing array. So if you have a slice of structs that only have e.g. int fields, you do not need to zero it, in fact it's just unnecessary extra work. If the struct has fields that are pointers, or slices, or e.g. other struct type that have pointers or slices etc., then you should zero it in order to remove the reference to the memory outside of the backing array.






share|improve this answer















Simplest can be demonstrated by a simple slice expression.



Let's start with a slice of *int pointers:



s := []*intnew(int), new(int)


This slice has a backing array with a length of 2, and it contains 2 non-nil pointers, pointing to allocated integers (outside of the backing array).



Now if we reslice this slice:



s = s[:1]


Length will become 1. The backing array (holding 2 pointers) is not touched, it sill holds 2 valid pointers. Even though we don't use the 2nd pointer now, since it is in memory (it is the backing array), the pointed object (which is a memory space for storing an int value) cannot be freed by the garbage collector.



The same thing happens if you "cut" multiple elements from the middle. If the original slice (and its backing array) was filled with non-nil pointers, and if you don't zero them (with nil), they will be kept in memory.



Why isn't this an issue with non-pointers?



Actually, this is an issue with all pointer and "header" types (like slices and strings), not just pointers.



If you would have a slice of type []int instead of []*int, then slicing it will just "hide" elements that are of int type which must stay in memory as part of the backing array regardless of if there's a slice that contains it or not. The elements are not references to objects stored outside of the array, while pointers refer to objects being outside of the array.



If the slice contains pointers and you nil them before the slicing operation, if there are no other references to the pointed objects (if the array was the only one holding the pointers), they can be freed, they will not be kept due to still having a slice (and thus the backing array).



Update:



When you have a slice of structs:



var bkSlice = []BooksBook1, Book2


If you slice it like:



bkSlice = bkSlice[:1]


Book2 will become unreachabe via bkSlice, but still will be in memory (as part of the backing array).



You can't nil it because nil is not a valid value for structs. You can however assign its zero value to it like this:



bkSlice[1] = Book
bkSlice = bkSlice[:1]


Note that a Books struct value will still be in memory, being the second element of the backing array, but that struct will be a zero value, and thus will not hold string references, thus the original book author and title strings can be garbage collected (if no one else references them; more precisely the byte slice referred from the string header).



The general rule is "recursive": You only need to zero elements that refer to memory located outside of the backing array. So if you have a slice of structs that only have e.g. int fields, you do not need to zero it, in fact it's just unnecessary extra work. If the struct has fields that are pointers, or slices, or e.g. other struct type that have pointers or slices etc., then you should zero it in order to remove the reference to the memory outside of the backing array.







share|improve this answer














share|improve this answer



share|improve this answer








edited Mar 7 at 15:43

























answered Mar 7 at 14:44









iczaicza

173k25350383




173k25350383












  • Thank you for the answer, I have updated the question, can you please check once.

    – Samarendra
    Mar 7 at 15:24











  • @Samarendra See edited answer.

    – icza
    Mar 7 at 15:28

















  • Thank you for the answer, I have updated the question, can you please check once.

    – Samarendra
    Mar 7 at 15:24











  • @Samarendra See edited answer.

    – icza
    Mar 7 at 15:28
















Thank you for the answer, I have updated the question, can you please check once.

– Samarendra
Mar 7 at 15:24





Thank you for the answer, I have updated the question, can you please check once.

– Samarendra
Mar 7 at 15:24













@Samarendra See edited answer.

– icza
Mar 7 at 15:28





@Samarendra See edited answer.

– icza
Mar 7 at 15:28



















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55045402%2fmemory-leak-in-golang-slice%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Identity Server 4 is not redirecting to Angular app after login2019 Community Moderator ElectionIdentity Server 4 and dockerIdentityserver implicit flow unauthorized_clientIdentityServer Hybrid Flow - Access Token is null after user successful loginIdentity Server to MVC client : Page Redirect After loginLogin with Steam OpenId(oidc-client-js)Identity Server 4+.NET Core 2.0 + IdentityIdentityServer4 post-login redirect not working in Edge browserCall to IdentityServer4 generates System.NullReferenceException: Object reference not set to an instance of an objectIdentityServer4 without HTTPS not workingHow to get Authorization code from identity server without login form

2005 Ahvaz unrest Contents Background Causes Casualties Aftermath See also References Navigation menue"At Least 10 Are Killed by Bombs in Iran""Iran"Archived"Arab-Iranians in Iran to make April 15 'Day of Fury'"State of Mind, State of Order: Reactions to Ethnic Unrest in the Islamic Republic of Iran.10.1111/j.1754-9469.2008.00028.x"Iran hangs Arab separatists"Iran Overview from ArchivedConstitution of the Islamic Republic of Iran"Tehran puzzled by forged 'riots' letter""Iran and its minorities: Down in the second class""Iran: Handling Of Ahvaz Unrest Could End With Televised Confessions""Bombings Rock Iran Ahead of Election""Five die in Iran ethnic clashes""Iran: Need for restraint as anniversary of unrest in Khuzestan approaches"Archived"Iranian Sunni protesters killed in clashes with security forces"Archived

Can't initialize raids on a new ASUS Prime B360M-A motherboard2019 Community Moderator ElectionSimilar to RAID config yet more like mirroring solution?Can't get motherboard serial numberWhy does the BIOS entry point start with a WBINVD instruction?UEFI performance Asus Maximus V Extreme