After adding the final touches to my program, I ran valgrind to check for memory leaks. And to my surprise, I read that huge chunks of memory were used and never deallocated, although I made sure I freed every resource I was using before ending the program. Looking closely at the report, I find that almost all of the report said the leaks were coming from libcurl function calls. Here's a sample from the report:
==3555== HEAP SUMMARY:
==3555== in use at exit: 179,937 bytes in 4,212 blocks
==3555== total heap usage: 18,080 allocs, 13,868 frees, 10,050,116 bytes allocated
==3555==
==3555== Searching for pointers to 4,212 not-freed blocks
==3555== Checked 486,368 bytes
==3555==
==3555== 2 bytes in 2 blocks are still reachable in loss record 1 of 667
==3555== at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3555== by 0x542C9C9: strdup (in /usr/lib/libc-2.20.so)
==3555== by 0x4E58C1E: ??? (in /usr/lib/libcurl.so.4.3.0)
==3555== by 0x4E6A90F: ??? (in /usr/lib/libcurl.so.4.3.0)
==3555== by 0x4E6B4A0: curl_multi_perform (in /usr/lib/libcurl.so.4.3.0)
==3555== by 0x404141: url_fopen (network.c:226)
==3555== by 0x403737: load_tracks (PlayMusic.c:718)
==3555== by 0x401E1C: main (PlayMusic.c:145)
==3555==
==3555== 2 bytes in 2 blocks are still reachable in loss record 2 of 667
==3555== at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3555== by 0x542C9C9: strdup (in /usr/lib/libc-2.20.so)
==3555== by 0x4E58C3A: ??? (in /usr/lib/libcurl.so.4.3.0)
==3555== by 0x4E6A90F: ??? (in /usr/lib/libcurl.so.4.3.0)
==3555== by 0x4E6B4A0: curl_multi_perform (in /usr/lib/libcurl.so.4.3.0)
==3555== by 0x404141: url_fopen (network.c:226)
==3555== by 0x403737: load_tracks (PlayMusic.c:718)
==3555== by 0x401E1C: main (PlayMusic.c:145)
Here is the url_fopen
function that valgrind complains about:
URL_FILE *url_fopen(const char *url, const char *operation)
{
/*
this code could check for URLs or types in the 'url' and
basicly use the real fopen() for standard files
*/
URL_FILE *file;
file = malloc(sizeof(URL_FILE));
if (!file)
return NULL;
memset(file, 0, sizeof(URL_FILE));
if ((file->handle.file = fopen(url, operation)))
file->type = CFTYPE_FILE; /* marked as URL */
else {
file->type = CFTYPE_URL; /* marked as URL */
file->handle.curl = curl_easy_init();
curl_easy_setopt(file->handle.curl, CURLOPT_URL, url);
curl_easy_setopt(file->handle.curl, CURLOPT_WRITEDATA,
file);
curl_easy_setopt(file->handle.curl, CURLOPT_VERBOSE,
0L);
curl_easy_setopt(file->handle.curl,
CURLOPT_WRITEFUNCTION,
write_callback);
if (!multi_handle)
multi_handle = curl_multi_init();
curl_multi_add_handle(multi_handle,
file->handle.curl);
/*
lets start the fetch
*/
curl_multi_perform(multi_handle,
&file->still_running);
if ((file->buffer_pos == 0) && (!file->still_running)) {
/*
if still_running is 0 now, we should return NULL
*/
/*
make sure the easy handle is not in the multi handle anymore
*/
curl_multi_remove_handle(multi_handle,
file->handle.curl);
/*
cleanup
*/
curl_easy_cleanup(file->handle.curl);
curl_multi_cleanup(multi_handle);
fclose
free(file);
file = NULL;
}
}
return file;
}
Are these just false positives ? If they are, how can I force valgrind to ignore them. If they are not, is there a solution to this leaking problem ?
Run the demo plunker in IE11. Hit F12 and go to the memory tab and start the memory analyzer. Additionally you can open Task Manger in Windows and watch the Memory Usage.
JavaScript code can experience memory leaks by keeping hidden references to objects. Hidden references can cause memory leaks in many unexpected ways.
console. log() causes memory leaks but only when the console is opened. Normally users do not open the console. So it is totally safe to print any huge objects to the console.
Try using curl_global_init(CURL_GLOBAL_DEFAULT);
at the start of the program. This sets the environment that libcURL
requires.
It is recommended that, this function must be called at least once within a program. Also it is not thread-safe so it must be called at the very beginning of the program, before any threads start.
Also you should call curl_global_cleanup();
once for each call to curl_global_init()
, at the end of the program when you are done using libcURL
.
This will clean up all things used by libcURL
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With