fwrite consume free memory continuously

Hi, I have noted this behavior when I wrote a program that has to save data on a file on a microcontroller with an Embedded Linux Operated System (ARM based, only 64RAM) and I checked also on a system with Ubuntu 10.04. To understand the problem I save about 4Mb on a file every 100ms. The memory of the process remains stable, but if I look to the total memory of the system (with vmstat 1) the free memory decrease continuously. Is it normal this behavior?
This is my code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>

static const char *FILELOG_PATH = "test";

int main(){
    const int LEN = 50000;
    double tmp[LEN];
    for(int i=0; i<LEN; ++i)
        tmp[i] = 1.1;

    FILE *file = fopen(FILELOG_PATH, "a");
    while(true){
	for(int i=0; i<10; ++i)
	    fwrite(&tmp, sizeof(double)*LEN,1,file);
	fflush(file);
		
	usleep(100*1000);
    }
    close(file);
    return 0;
}
It can be. Where is the free memory going? Is the buffer cache increasing? The buffer cache is the page cache used by the kernel to store off disk pages so that if they are later needed, they can be loaded directly from RAM rather than accessing the physical disk (orders of magnitude slower).
When you say "Memory" are you refering to the physical RAM? Or the Disk space? Some people don't make the distiction and I wanted to make sure we are all on the same page.

If you mean the free disk space is decreasing, it's because you have fopen set to append data to the end of the file.
No, I am referring to the RAM.
These are the last lines output of vmstat (starting from 1430860 of free memory)

procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 0  0      0 777084 146164 2516584    0    0     0 74612 1088 1508  3  2 94  0
 1  0      0 742008 146164 2551632    0    0     0     0 1437 2256  2  3 95  0
 0  1      0 721788 146168 2571224    0    0     0 73816 1021 1369  1  3 82 13
 0  0      0 690344 146172 2602428    0    0     0     4 1329 2093  2  3 89  7
 0  1      0 649012 146176 2641580    0    0     0 74760 1139 1622  2  4 91  3
 0  0      0 614896 146180 2676704    0    0     0     4 1568 2195  2  3 77 18
 0  0      0 574556 146180 2716688    0    0  1116 73640 1326 1736  3  5 81 10
 0  0      0 536228 146188 2755816    0    0     0    60 1521 2307  3  3 84 10
 0  0      0 494836 146188 2794916    0    0     0 74856 1109 1531  3  3 94  0
 0  0      0 460788 146188 2830072    0    0     0     0 1550 2284  3  2 94  0
 0  0      0 419960 146196 2869216    0    0     0 71484 1369 1646  2  4 85 10
 1  0      0 381424 146196 2908284    0    0     0     0 1481 2081  3  2 95  0
 0  1      0 344372 146200 2943408    0    0     0 73360 1178 1772  3  3 83 11
 0  0      0 305868 146204 2982468    0    0     0     4 1513 2401  3  2 76 19
 0  0      0 265148 146204 3021552    0    0     0 71220 1169 1628  3  3 94  0
 1  0      0 226436 146212 3060628    0    0     0    40 1341 1996  2  2 87  9
 0  0      0 189972 146212 3095704    0    0     0 73340 1228 1730  2  3 95  0
 0  0      0 151080 146220 3134840    0    0     0    32 1443 2188  2  3 95  1
 0  0      0 122428 143916 3164376    0    0     0 71244 1255 1576  2  4 93  0
 1  0      0 122080 136552 3171564    0    0     0     0 1635 2491  3  3 94  0
 0  0      0 118420 129904 3181408    0    0     0 73520 1887 2663  4  4 91  1
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 0  0      0 118932 123288 3187852    0    0     0     0 2046 3215  3  2 95  0
 1  1      0 118716 116332 3194848    0    0     0 74520 1884 2760  2  4 87  7
 0  0      0 121484 109432 3199276    0    0     0     4 2034 3247  2  4 92  3
 0  0      0 121308 101496 3206836    0    0     0 74768 1921 2749  2  2 95  0
 1  0      0 123232  91144 3213880    0    0     0 73788 1936 2931  3  3 93  1
 0  0      0 123856  83580 3222436    0    0     0     0 1598 2224  4  2 94  0
 0  0      0 122672  83588 3221680    0    0     0 70904 1545 2325  4  3 90  2
 1  0      0 118852  83588 3226820    0    0     0     0 1272 1656  4  2 94  0
 0  0      0 117568  83588 3225544    0    0     0 73948 1537 2212  4  3 93  0
 0  0      0 118972  83596 3225772    0    0     0    76 1361 1743  4  2 78 15
 1  0      0 121964  83596 3221352    0    0     0 74536 1548 2170  4  3 93  0
 0  0      0 121624  83604 3223680    0    0     0    68 1295 1648  4  2 91  4
 0  0      0 118460  83604 3224864    0    0     0 74208 1563 2216  4  3 93  0
 1  0      0 121836  83604 3223460    0    0     0     0 1292 1631  4  2 94  0
 0  0      0 122812  83612 3220708    0    0     0 74372 1496 2142  3  3 93  1
 0  0      0 118644  83612 3226472    0    0     0     0 1352 1725  4  2 94  0
 1  1      0 121776  83608 3222104    0    0     0 74064 1482 2124  4  3 89  4
 0  0      0 121548  83612 3223812    0    0     0     4 1438 2170  4  2 74 20
 0  0      0 120544  83612 3223344    0    0     0 74312 1552 2297  2  3 94  0
 0  0      0 122876  83620 3222804    0    0     0    40 1238 1567  2  3 90  5
 0  0      0 120452  83620 3223704    0    0     0 74392 1463 2135  1  3 96  0


So, free memory decrease and also the buffer, and cache seems to increase.
This behavior is normal, or it could be dangerous for the system?
Normal behavior. The data you are writing (to disk) is being written to the page cache as well, and the kernel will expand the page cache as long as there is memory available (to a certain point).
Have you ever wondered why opening of firefox takes longer for the first time? Next time onwards it is fast. The reason is, even if you close the program, the image of the hard disk still persists in the RAM.

I have seen it quite often with my program. My program is a movie processor which reads a movie frame by frame from the disk. But as soon as the processing of a frame is over, it frees the memory and loads the next frame. So memory consumption should be at most one frame. However the OS continues to keep all read frame in the RAM till it is full. I am having 2GB RAM in my computer. And the kernel goes on caching till it is full. If I put 4GB, then it will go up to 4GB. I don't know where it ends. I have to test it on a workstation having 32GB RAM and running 64bit linux.
However the OS continues to keep all read frame in the RAM till it is full. I am having 2GB RAM in my computer. And the kernel goes on caching till it is full. If I put 4GB, then it will go up to 4GB. I don't know where it ends. I have to test it on a workstation having 32GB RAM and running 64bit linux.


If you don't mind I'd like to see your code in a new thread krishnendu, this shouldn't happen if you're using destructors and\or delete commands properly. A modern OS will only give an application more RAM if it hits a page fault, this occurs when the application has or is about exceed it's allocated memory. If you are destroying objects there by releasing the memory and allowing the system to designate the addresses of your variables then a page fault should never occur.

As for the "Image persisting in RAM" bit, there is a periodic process called a "Garbage Collector" that cleans this stuff up. When a thread does not have any open handles to it then the memory space for that thread is marked as avalible for the OS. The OP is seeing their issue because it is occuring at run time, the "Garbage Collector" will not release the memory because it is still in use.
Last edited on
I have not said that my program is using the memory. If you run 'top' in Linux, it tells you about the total available memory, memory used as a whole (i.e. both by the OS and applications) and free memory. It is the 'used memory' which keeps on increasing. The 'top' command also shows the memory used by an individual process. There I can see that the memory used by my program is not increasing. Any way try the following code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <string>
#include <fstream>
#include <iostream>

using namespace std;

#define FILE_SIZE_1KB 1024
#define FILE_SIZE_1MB (1024 * FILE_SIZE_1KB)
#define FILE_SIZE_1GB (1024 * FILE_SIZE_1MB)
#define FILE_SIZE_256MB (256 * FILE_SIZE_1MB)
#define FILE_SIZE_512MB (512 * FILE_SIZE_1MB)

#define FILE_SIZE FILE_SIZE_256MB
// Change it according to you RAM

const char *filename = "zeros.bin";

void writer (void)
{
	ofstream output;
	output.open (filename);
	cout << "Writing " << filename << endl;

	for (int32_t i = 0; i < FILE_SIZE; i++) {

		output.put ('\0');

		if (i % FILE_SIZE_1MB == 0) {
			cout << (i + 1) / FILE_SIZE_1MB << "MB\r";
			cout.flush ();
		}
	}
	cout << endl;

	output.close ();
	cout << "Writing over. Now run read." << endl;
}

void reader (void)
{
	ifstream input;
	input.open (filename);
	cout << "Reading " << filename << endl;
	cout << "Watch you hard-disk LED. Is it blinking?" << endl;

	for (int32_t i = 0; input.good (); i++) {

		input.get ();

		if (i % FILE_SIZE_1MB == 0) {

			cout << i / FILE_SIZE_1MB << "MB\r";
			cout.flush ();
		}
	}
	cout << endl;

	input.close ();
	cout << "Reading over" << endl;
	cout << "Reboot your computer. "
	"Run this program (read) twice and watch the LED." << endl;
}

int main (int argc, char *argv[])
{
	const char *usage =
		"Usage:\n"
		"\t<program> write\n"
		"\t<program> read\n";

	if ((argc >= 2) && (string (argv[1]) == "write"))
		writer ();
	else if ((argc >= 2) && (string (argv[1]) == "read"))
		reader ();
	else
		cout << usage << endl;
}
Topic archived. No new replies allowed.