gomemory-leakslz4pprof

Memory is not being released


This is a simple program to decompress the string, I just running a loop to show that memory usage increases and the memory used never get released.

Memory is not getting released even after 8hr also

Package for decompressing string: https://github.com/Albinzr/lzGo - (simple lz string algorithm)

I'm adding a gist link since the string used for decompressing is large

Source Code: Code

enter image description here

Activity Monitor enter image description here

I'm completely new to go, Can anyone tell me how I can solve the memory issue?

UPDATE Jul 15 20 The app still crashes when the memory limit is reached Since it only uses 12mb - 15mb this should not happen!!


Solution

  • There is a lot going on here.

    First, using Go version 1.14.2 your program works fine for me. It does not appear to be leaking memory.

    Second, even when I purposely created a memory leak by increasing the loop size to 100 and saving the results in an array, I only used about 100 MB of memory.

    Which gets us to Third, you should not be using Activity Monitor or any other operating system level tools to be checking for memory leaks in a Go program. Operating System memory management is a painfully complex topic and the OS tools are designed to help you determine how a program is affecting the whole system, not what is going on within the program.

    Specifically, macOS "Real Memory" (analogous to RSS, Resident Set Size) includes memory the program is no longer using but the OS has not taken back yet. When the garbage collector frees up memory and tells the OS it does not need that memory anymore, the OS does not immediately take it back. (Why it works that way is way beyond the scope of this answer.) Also, if the OS is under Memory Pressure, it can take back not only memory the program has freed, but it can also take back (temporarily) memory the program is still using but has not accessed "recently" so that another program that urgently needs memory can use it. In this case, "Real Memory" will be reduced even if the process is not actually using less memory. There is no statistic reported by the operations system that will help you here.

    You need to use native Go settings like GODEBUG=gctrace=1 or tools like expvar and expvarmon to see what the garbage collector is doing.

    As for why your program ran out of memory when you limited it, keep in mind that by default Go builds a dynamically linked executable and just reading in all the shared libraries can take up a lot of memory. Try building your application with static linking using CGO_ENABLED=0 and see if that helps. See how much memory it uses when you only run 1 iteration of the loop.