LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices


Reply
  Search this Thread
Old 09-01-2005, 05:10 PM   #1
sarunya
LQ Newbie
 
Registered: Aug 2005
Posts: 7

Rep: Reputation: 0
kernel 2.6.13 - space not freed to kernel


i have a program that all it does is to allocate memory up until consume 1GB of free resources. but when i delete it, it seemed that the space is not free to kernel, (notice this by looking at "top" or meminfo, as well as debug messages prinf the memory info. using sysinfo (system call). this happens on mainline kernel 2.6.13 but not on other Redhat distros (RHEL3/RHEL4).

so it seemed that on mainline 2.6.13, when the userprocess allocate mem and free it mem, the freed memory is not returned back to the kernel... is this a possible bug????
 
Old 09-01-2005, 05:16 PM   #2
Komakino
Senior Member
 
Registered: Feb 2004
Location: Somerset, England
Distribution: Slackware 10.2, Slackware 10.0, Ubuntu 9.10
Posts: 1,938

Rep: Reputation: 55
How does it allocate all this space? Are you making multiple calls to 'malloc()' or similar? If you close the program without making the subsequent calls to free() (for the total amount of memory malloc'd) then the memory won't be freed back for other programs to use and so will remain in use.
 
Old 09-01-2005, 07:01 PM   #3
sarunya
LQ Newbie
 
Registered: Aug 2005
Posts: 7

Original Poster
Rep: Reputation: 0
Please Observe this test program:
Assumption: in main() the space (units in KB) to allocate is 1GB, if you machine has less than that use lower space value- 100MB (to be left to avoid oom killer).
Idea: allocate using a linked list to as many nodes as it required to filled up 1GB or less of address space

Result: on RHEL3 or 4, after the program allocate nodes, and then deallocate it, sysinfo indicate the memory that were freed are returned to the kernel.
on 2.6.13, after the proram allocate nodes, and then deallocate it, sysinfo give the free{ram+swap} to be about the same as it was after the node finish
allocating, seemed like the freed nodes address space were not returned to the kernel

any ideaS?
**************************************************************************************************** ***********************************************
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/sys.h>
#include <linux/kernel.h>
#include <sys/types.h>
#include <sys/sysinfo.h>



//////////////////////// CONST DATA ///////////////////////////////
#define LIMIT 102400 /* = 100MB (Units in KB) */
#define KB_VALUE 1024 /* Unit in bytes */
#define ARR_SIZE 1024 /* array size for item data in node */
///////////////////////////////////////////////////////////////////



/********************************************************************
* Node Data Structure for LLL
* size of this struct ~ 64 Bytes
********************************************************************/
struct node
{
int item[ARR_SIZE];
struct node * next;
};



////////////////////////////// GLOBAL DATA ////////////////////////////
struct node * head = NULL; /* head of LLL */
long unsigned count_create = 0;
long unsigned count_destroy= 0;
///////////////////////////////////////////////////////////////////////



/**********************************************************************
* Add a Node to LLL; data Uninitialized
* Return: 1=succeed; 0=failed
**********************************************************************/
int
lll_add()
{
int i;
struct sysinfo si;

struct node *tmp = (struct node *)malloc(sizeof(struct node));
if(tmp == NULL) {
sysinfo(&si);
printf("freeram (%lu), freeswap (%lu), totalram (%lu), totalswap (%lu)\n",
si.freeram * si.mem_unit / KB_VALUE,
si.freeswap * si.mem_unit / KB_VALUE,
si.totalram * si.mem_unit / KB_VALUE,
si.totalswap * si.mem_unit / KB_VALUE);
fprintf(stderr,"ERROR: FAILED MALLOC\n");
return 0;
} else {
/* Write data here so space got from malloc is reserved */
++count_create;
for(i = 0; i < ARR_SIZE; ++i)
tmp->item[i] = 0;
tmp->next= head;
head = tmp;
return 1;
}
}



int
lll_destroy_all()
{
struct node * tmp = head;

while(tmp != NULL) {
head = tmp->next;
free(tmp);
++count_destroy;
tmp = head;
}

return 1;
}



/**********************************************************************
* Allocating nodes according to the input space specified
* Assuming that input space is in KB, and free{ram+swap} > space +
LIMIT (which is currently 100 MB)
**********************************************************************/
int
lll_eat(long unsigned space)
{
struct sysinfo si;
struct sysinfo si2;

sysinfo(&si);
sysinfo(&si2);

while( ((si.freeram * si.mem_unit / KB_VALUE) + (si.freeswap* si.mem_unit / KB_VALUE) -
(si2.freeram* si2.mem_unit / KB_VALUE) - (si2.freeswap* si2.mem_unit / KB_VALUE)) <=
(space)) {
if(lll_add() <= 0) {
perror("lll_add failed in lll_eat before done allocating specified space\n");
return 0;
}

sysinfo(&si2);
}

sysinfo(&si2);
printf("After Done lll_eat.... \n");
printf("BEFORE : freeram (%lu), freeswap (%lu), totalram (%lu), totalswap (%lu)\n",
si.freeram * si.mem_unit / KB_VALUE,
si.freeswap * si.mem_unit / KB_VALUE,
si.totalram * si.mem_unit / KB_VALUE,
si.totalswap * si.mem_unit / KB_VALUE);
printf("AFTER : freeram (%lu), freeswap (%lu), totalram (%lu), totalswap (%lu)\n",
si2.freeram * si2.mem_unit / KB_VALUE,
si2.freeswap * si2.mem_unit / KB_VALUE,
si2.totalram * si2.mem_unit / KB_VALUE,
si2.totalswap * si2.mem_unit / KB_VALUE);
return 1;
}



int
main(int argc, char ** argv)
{
int status;
int path;
pid_t spid;

struct sysinfo si;
long unsigned space = 1048576; // alloc 1 GB (unit here in KB)

///////////////////////////// DEBUGGING ///////////////////////////////////////
sysinfo(&si);
printf("Before a.out parent (pid=%d) start.... \n", getpid());
printf("freeram (%lu), freeswap (%lu), totalram (%lu), totalswap (%lu)\n",
si.freeram * si.mem_unit / KB_VALUE,
si.freeswap * si.mem_unit / KB_VALUE,
si.totalram * si.mem_unit / KB_VALUE,
si.totalswap * si.mem_unit / KB_VALUE);
////////////////////////////////////////////////////////////////////////////////


if(!lll_eat(space)) {
perror("Fail lll_eat\n");
exit(1);
}

printf("Done eating... Now Destroying\n");
sleep(5);

lll_destroy_all();

printf("Done destroying...\n");

printf("Created= %lu nodes, Destroyed= %lu nodes\n", count_create, count_destroy);

//////////////////////////// DEBUGGING ///////////////////////////////////////////////////
sysinfo(&si);
printf("After a.out parent exiting.... \n");
printf("freeram (%lu), freeswap (%lu), totalram (%lu), totalswap (%lu)\n",
si.freeram * si.mem_unit / KB_VALUE,
si.freeswap * si.mem_unit / KB_VALUE,
si.totalram * si.mem_unit / KB_VALUE,
si.totalswap * si.mem_unit / KB_VALUE);
////////////////////////////////////////////////////////////////////////////////////////////

return 0;
}
 
Old 09-01-2005, 08:38 PM   #4
btmiller
Senior Member
 
Registered: May 2004
Location: In the DC 'burbs
Distribution: Arch, Scientific Linux, Debian, Ubuntu
Posts: 4,290

Rep: Reputation: 378Reputation: 378Reputation: 378Reputation: 378
A lot of times, particularly with large memory allocations, the kernel won't actually assign you memory until you try to do something with it (i.e. read or write from it), which your code does not appear to do. Also, the kernel caches memory extremely aggressively, so if you free memory, thew kernel may not actually free it in case your app wants it again (of course if another app asks for it the kernel will give it to that app). I suggest you take a look at the vm sysctl variables and what they do for a further explanation.

Oh, and please put code in code tags -- makes it much easier to read.
 
Old 09-02-2005, 04:29 AM   #5
addy86
Member
 
Registered: Nov 2004
Location: Germany
Distribution: Debian Testing
Posts: 332

Rep: Reputation: 31
Quote:
Originally posted by Komakino
How does it allocate all this space? Are you making multiple calls to 'malloc()' or similar? If you close the program without making the subsequent calls to free() (for the total amount of memory malloc'd) then the memory won't be freed back for other programs to use and so will remain in use.
This is not true. Every at least partially sane OS (like Linux) will free all memory dedicated to a process when that process dies.
 
Old 09-02-2005, 05:59 AM   #6
Komakino
Senior Member
 
Registered: Feb 2004
Location: Somerset, England
Distribution: Slackware 10.2, Slackware 10.0, Ubuntu 9.10
Posts: 1,938

Rep: Reputation: 55
Quote:
Originally posted by addy86
This is not true. Every at least partially sane OS (like Linux) will free all memory dedicated to a process when that process dies.
I stand (or rather sit) corrected.

Was this the case at one time, or have I made the whole thing up?
 
Old 09-02-2005, 09:14 AM   #7
sarunya
LQ Newbie
 
Registered: Aug 2005
Posts: 7

Original Poster
Rep: Reputation: 0
btmiller,

"A lot of times, particularly with large memory allocations, the kernel won't actually assign you memory until you try to do something with it (i.e. read or write from it), which your code does not appear to do. "
=>It is true that malloc won't actually assigned the space until the return address from malloc is being write or read from. but Please look at lll_add() which is a a node into the linked list, when malloc passed, it would go into the else condition to create a node, as well as, WRITE a value 0, to all data, now you see that the code actually write value to ALL data for EVERY nodes.


"Also, the kernel caches memory extremely aggressively, so if you free memory, thew kernel may not actually free it in case your app wants it again (of course if another app asks for it the kernel will give it to that app)."
=>So why is it then the memory was freed after lll_destroy_all on RHEL3 or RHEL4 but not on kernel 2.6.13?
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
file deleted, but no space freed kpachopoulos Linux - General 3 02-07-2008 10:43 AM
'Freeing Unused Kernel Memory: 224k Freed - Laptop Hangs nutnut Linux - Laptop and Netbook 1 10-21-2005 07:09 PM
Freeing unused kernel memory: 136k freed apenguinlinux Debian 8 08-08-2005 03:30 PM
kernel memory + slabinfo.. + possible reasons for kernel space allocation failures!! premenjit Linux - Software 1 09-28-2004 04:13 AM
Freeing unused kernel memory: 228k freed bodedeb Linux - General 8 10-28-2003 03:59 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - General

All times are GMT -5. The time now is 09:15 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration