Can anyone explain why I get a memory leak (+1.55 kB) with code below and what am I supposed to do to avoid it ?
void TestGuid() {
UUID id;
ZeroMemory(&id, sizeof(UUID));
UuidCreate(&id);
}
int _tmain(int argc, _TCHAR* argv[]) {
TestGuid(); // Memory Snapshot 1 here
return 0; // Memory Snapshot 2 here
}
The very first call of UuidCreate makes some allocations. The first snapshot shows what was allocated, it seems it's related to initialization of random numbers generator:
But if you call UuidCreate once again, no new allocations are made. The second screenshot shows that no leaks found. So formally there are leaks but you can't fix it, and it's not a big deal - very few memory allocated.
Related
I have the following program:
int main(int argc,char **argv){
double*a;
double*b;
double*c;
double*d;
double*e;
double*f;
double*g;
double*h;
double*i;
double*j;
double*k;
double*l;
double*m;
double*n;
double*o;
double*p;
double*q;
while(1){
a=malloc(1000000*1000000000000*sizeof(double));
b=malloc(1000000*1000000000000);
c=malloc(1000000*1000000000000);
d=malloc(1000000*1000000000000);
e=malloc(1000000*1000000000000);
f=malloc(1000000*1000000000000);
g=malloc(1000000*1000000000000);
h=malloc(1000000*1000000000000);
i=malloc(1000000*1000000000000);
j=malloc(1000000*1000000000000);
m=malloc(1000000*1000000000000);
n=malloc(1000000*1000000000000);
o=malloc(1000000*1000000000000);
p=malloc(1000000*1000000000000);
q=malloc(1000000*1000000000000);
}
}
and the task manager issues the following memory usage:
I, then, changed the program to
int main(int argc,char **argv){
double*a;
while(1){
a=malloc(1000000*1000000000000*sizeof(double));
}
}
compiled it, and task manager showed:
Shouldn't memory usage be higher in the first program? What am I missing here?
Memory allocators like the glibc memory allocator have memory limits. This means making huge allocations could end up on a failed allocation. A NULL pointer is returned in such cases.
Check out return value of those mallocs to see what is happening, tho it is obvious that the request is too long to be allocated.
I was wondering how to know how many memory is my program using in real time. I find the PrintMemoryInfo() fuction in win32, and i tried to implement it.
CODE
#include <windows.h>
#include <stdio.h>
#include <psapi.h>
size_t PrintMemoryInfo()
{
PROCESS_MEMORY_COUNTERS info;
GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) );
return (size_t)info.WorkingSetSize;
}
inline void printIt(){
double memory = (double)PrintMemoryInfo() * 0.001;
printf("%.2f kb\n",memory);
}
int main( void )
{
printIt();
char *i =(char*)malloc(100000);
printIt();
free(i);
printIt();
return 0;
PROCESS_MEMORY_COUNTERS contains the memory statistics of a process and GetProcessMemoryInfo fill it out with the data. I need to know the actual memory size has been using by the program, so i used WorkingSetSize for obtain that.
Microsoft definition:
WorkingSetSize
The current working set size, in bytes.
i passed from bytes to kilobytes and wieh i execute the program i obtain this:
output
1974.27 kb
2027.52 kb
2035.71 kb
this program make no sense to me:
almost 2 mb of memory for a program doing nothing?.
allocated 100 kb of memory but the program is using only 67 kb more.
if i freed the memory why this grows up.
Maybe i didn't get what this functions are doing, so can someone explain me what is going on please?
Thank you!
It is sum of :
size of execute file
stack memory memory that your program occupies the static variables that you use in your program
heap memory memory that your program takes a dynamic variable
and size of libraries that is use in program.
Program alloc more memory, for construct the code.
I have a problem with memory fragmentation which can be summarized in this small example:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
void *p[8000];int i,j;
p[0]=malloc(0x7F000);
if (p[0]==NULL)
printf("Alloc after failed!\n");
else
free(p[0]);
for (i=0;i<8000; i++) {
p[i]=malloc(0x40000);
if (p[i]==NULL){
printf("alloc failed for i=%d\n",i);
break;
}
}
for(j=0;j<i;j++) {
free(p[j]);
}
/*Alloc 1 will fail, Alloc 2 *might* fail, AlloC3 succeeds*/
p[0]=malloc(0x7F000);
if (p[0]==NULL)
printf("Alloc1 after failed!\n");
else {printf("alloc1 success\n");free(p[0]);}
p[0]=malloc(0x40000);
if (p[0]==NULL)
printf("Alloc2 after failed!\n");
else {printf("alloc2 success\n");free(p[0]);}
p[0]=malloc(0x10000);
if (p[0]==NULL)
printf("Alloc3 after failed!\n");
else {printf("alloc3 success\n");free(p[0]);}
printf("end");
}
The program prints (compiled with MSVC (both with debug and releas allocator) and MinGW on Win7):
alloc failed for i=7896
Alloc1 after failed!
alloc2 success
alloc3 success
end
Is there anyway I can avoid this? In my real application I can't avoid the scenario, my program reaches the 2GB memory limit... but I want to be able to continue by free-ing something.
Why is the fragmentation happening here in this small example in the first place? When I start to do the "free-s" why aren't the memory blocks compacted, as they should be adjacent.
Thanks!
Memory fragmentation is the consequence of allocating memory of varying sizes, each with varying lifespans. This is what creates holes in the free memory that in total are sufficient to satisfy a single allocation request, but each hole is too small by itself.
The situation in your program seems to be revealing a bug your heap management code that is not coalescing adjacent freed memory. I do expect there is a single 64 KB hole created by your allocation sequence.
To avoid this particular problem, I would simply hold on to the first allocation when I am done with it, storing it in my own "free list" so to speak. Then next time I need it, I take it from the "free list" rather than calling malloc().
I need ideas on how to write a C program that reserve a specified amount of MB RAM until a key [ex. the any key] is pressed on a Linux 2.6 32 bit system.
*
/.eat_ram.out 200
# If free -m is execute at this time, it should report 200 MB more in the used section, than before running the program.
[Any key is pressed]
# Now all the reserved RAM should be released and the program exits.
*
It is the core functionality of the program [reserving the RAM] i do not know how to do, getting arguments from the commandline, printing [Any key is pressed] and so on is not a problem from me.
Any ideas on how to do this?
You want to use malloc() to do this. Depending on your need, you will also want to:
Write data to the memory so that the kernel actually guarantees it. You can use memset() for this.
Prevent the memory from being paged out (swapped), the mlock() / mlockall() functions can help you with this.
Tell the kernel how you actually intend to use the memory, which is accomplished via posix_madvise() (this is preferable to an explicit mlockall()).
In most realities, malloc() and memset() (or, calloc() which effectively does the same) will suit your needs.
Finally, of course, you want to free() the memory when it is no longer needed.
Can't you just use malloc() to allocate that ram to your process? That will reserve that RAM for you, and then you are free to do whatever you wish with it.
Here's an example for you:
#include <stdlib.h>
int main (int argc, char* argv[]) {
int bytesToAllocate;
char* bytesReserved = NULL;
//assume you have code here that fills bytesToAllocate
bytesReserved = malloc(bytesToAllocate);
if (bytesReserved == NULL) {
//an error occurred while reserving the memory - handle it here
}
//when the program ends:
free(bytesReserved);
return 0;
}
If you want more information, have a look at the man page (man malloc in a linux shell). If you aren't on linux, have a look at the online man page.
calloc() is what you want. It will reserve memory for your process and write zero's to it. This ensures that the memory is actually allocated for your process. If you malloc() a large portion of memory, the OS may be lazy about actually allocating memory for you, only actually allocating it when it is written to (which will never happen in this case).
You will need:
malloc() to allocate however many bytes you need (malloc(200000000) or malloc(20 * (1 << 20))).
getc() to wait for a keypress.
free() to deallocate the memory.
The information on these pages should be helpful.
Did this, should work. Although I was able to reserve more RAM than I have installed, this should work for valid values, tho.
#include <stdio.h>
#include <stdlib.h>
enum
{
MULTIPLICATOR = 1024 * 1024 // 1 MB
};
int
main(int argc, char *argv[])
{
void *reserve;
unsigned int amount;
if (argc < 2)
{
fprintf(stderr, "usage: %s <megabytes>\n", argv[0]);
return EXIT_FAILURE;
}
amount = atoi(argv[1]);
printf("About to reserve %ld MB (%ld Bytes) of RAM...\n", amount, amount * MULTIPLICATOR);
reserve = calloc(amount * MULTIPLICATOR, 1);
if (reserve == NULL)
{
fprintf(stderr, "Couldn't allocate memory\n");
return EXIT_FAILURE;
}
printf("Allocated. Press any key to release the memory.\n");
getchar();
free(reserve);
printf("Deallocated reserved memory\n");
return EXIT_SUCCESS;
}
I would like to write a program to consume all the memory available to understand the outcome. I've heard that linux starts killing the processes once it is unable to allocate the memory.
Can anyone help me with such a program.
I have written the following, but the memory doesn't seem to get exhausted:
#include <stdlib.h>
int main()
{
while(1)
{
malloc(1024*1024);
}
return 0;
}
You should write to the allocated blocks. If you just ask for memory, linux might just hand out a reservation for memory, but nothing will be allocated until the memory is accessed.
int main()
{
while(1)
{
void *m = malloc(1024*1024);
memset(m,0,1024*1024);
}
return 0;
}
You really only need to write 1 byte on every page (4096 bytes on x86 normally) though.
Linux "over commits" memory. This means that physical memory is only given to a process when the process first tries to access it, not when the malloc is first executed. To disable this behavior, do the following (as root):
echo 2 > /proc/sys/vm/overcommit_memory
Then try running your program.
Linux uses, by default, what I like to call "opportunistic allocation". This is based on the observation that a number of real programs allocate more memory than they actually use. Linux uses this to fit a bit more stuff into memory: it only allocates a memory page when it is used, not when it's allocated with malloc (or mmap or sbrk).
You may have more success if you do something like this inside your loop:
memset(malloc(1024*1024L), 'w', 1024*1024L);
In my machine, with an appropriate gb value, the following code used 100% of the memory, and even got memory into the swap.
You can see that you need to write only one byte in each page: memset(m, 0, 1);,
If you change the page size: #define PAGE_SZ (1<<12) to a bigger page size: #define PAGE_SZ (1<<13) then you won't be writing to all the pages you allocated, thus you can see in top that the memory consumption of the program goes down.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PAGE_SZ (1<<12)
int main() {
int i;
int gb = 2; // memory to consume in GB
for (i = 0; i < ((unsigned long)gb<<30)/PAGE_SZ ; ++i) {
void *m = malloc(PAGE_SZ);
if (!m)
break;
memset(m, 0, 1);
}
printf("allocated %lu MB\n", ((unsigned long)i*PAGE_SZ)>>20);
getchar();
return 0;
}
A little known fact (though it is well documented) - you can (as root) prevent the OOM killer from claiming your process (or any other process) as one of its victims. Here is a snippet from something directly out of my editor, where I am (based on configuration data) locking all allocated memory to avoid being paged out and (optionally) telling the OOM killer not to bother me:
static int set_priority(nex_payload_t *p)
{
struct sched_param sched;
int maxpri, minpri;
FILE *fp;
int no_oom = -17;
if (p->cfg.lock_memory)
mlockall(MCL_CURRENT | MCL_FUTURE);
if (p->cfg.prevent_oom) {
fp = fopen("/proc/self/oom_adj", "w");
if (fp) {
/* Don't OOM me, Bro! */
fprintf(fp, "%d", no_oom);
fclose(fp);
}
}
I'm not showing what I'm doing with scheduler parameters as its not relevant to the question.
This will prevent the OOM killer from getting your process before it has a chance to produce the (in this case) desired effect. You will also, in effect, force most other processes to disk.
So, in short, to see fireworks really quickly...
Tell the OOM killer not to bother you
Lock your memory
Allocate and initialize (zero out) blocks in a never ending loop, or until malloc() fails
Be sure to look at ulimit as well, and run your tests as root.
The code I showed is part of a daemon that simply can not fail, it runs at a very high weight (selectively using the RR or FIFO scheduler) and can not (ever) be paged out.
Have a look at this program.
When there is no longer enough memory malloc starts returning 0
#include <stdlib.h>
#include <stdio.h>
int main()
{
while(1)
{
printf("malloc %d\n", (int)malloc(1024*1024));
}
return 0;
}
On a 32-bit Linux system, the maximum that a single process can allocate in its address space is approximately 3Gb.
This means that it is unlikely that you'll exhaust the memory with a single process.
On the other hand, on 64-bit machine you can allocate as much as you like.
As others have noted, it is also necessary to initialise the memory otherwise it does not actually consume pages.
malloc will start giving an error if EITHER the OS has no virtual memory left OR the process is out of address space (or has insufficient to satisfy the requested allocation).
Linux's VM overcommit also affects exactly when this is and what happens, as others have noted.
I just exexuted #John La Rooy's snippet:
#include <stdlib.h>
#include <stdio.h>
int main()
{
while(1)
{
printf("malloc %d\n", (int)malloc(1024*1024));
}
return 0;
}
but it exhausted my memory very fast and cause the system hanged so that I had to restart it.
So I recommend you change some code.
For example:
On my ubuntu 16.04 LTS the code below takes about 1.5 GB ram, physical memory consumption raised from 1.8 GB to 3.3 GB after executing and go down back to 1.8GiB after finishing execution.Though it looks like I have allocate 300GiB ram in the code.
#include <stdlib.h>
#include <stdio.h>
int main()
{
while(int i<300000)
{
printf("malloc %p\n", malloc(1024*1024));
i += 1;
}
return 0;
}
When index i is less then 100000(ie, allocate less than 100 GB), either physical or virtual memory are just very slightly used(less then 100MB), I don't know why, may be there is something to do with virtual memory.
One thing interesting is that when the physical memory begins to shrink, the addresses malloc() returns definitely changes, see picture link below.
I used malloc() and calloc(), seems that they behave similarily in occupying physical memory.
memory address number changes from 48 bits to 28 bits when physical memory begins shrinking
I was bored once and did this. Got this to eat up all memory and needed to force a reboot to get it working again.
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char** argv)
{
while(1)
{
malloc(1024 * 4);
fork();
}
}
If all you need is to stress the system, then there is stress tool, which does exactly what you want. It's available as a package for most distros.