Re: memory allocation with malloc

2008-08-06 Thread Derek Ragona

At 01:16 AM 8/5/2008, Shyamal Shukla wrote:

Hi All,

 I am trying to validate my understanding of how malloc works by means
of the below C program which tries to corrupt essential information
maintained by malloc for free() operation.

The program allocates 4, 12 byte blocks (internally 16 bytes are allocated
for each 12 byte block). Hence the total allocated space was 48 bytes.

As malloc maintains the (length of allocated block + 1), 4 bytes before the
returned pointer (from malloc), I have manipulated this length for the first
block and set it to 49 with the goal that a single free shall release all
these 4 blocks and a subsequent malloc of 15 bytes shall be from the address
of first block.

However, this does not happen. Can someone please correct my understanding
and provide me with a reference to the working of malloc() and free()?

#includestdio.h

int main(void)
{
char * ptr,* ptr1, *ptr2, * ptr3, * ptr4;
int * i;
int n,q,p;
int loop = 0;

ptr1 = (char *)malloc(12);
i = (int *)(ptr1 - 4);
printf(\n ptr1 = %p,%d \n,ptr1,*i);
printf(\n %d:%d:%d:%d\n,ptr1[-4],ptr1[-3],ptr1[-2],ptr1[-1]);
printf(\n %d:%d:%d:%d\n,ptr1[0],ptr1[1],ptr1[2],ptr1[3]);
printf(\n %d:%d:%d:%d\n,ptr1[4],ptr1[5],ptr1[6],ptr1[7]);
printf(\n %d:%d:%d:%d\n,ptr1[8],ptr1[9],ptr1[10],ptr1[11]);
*i = 49;

ptr2 = (char *)malloc(12);
i = (int *)(ptr2 - 4);
printf(\n ptr2 = %p,%d \n,ptr2,*i);
printf(\n %d:%d:%d:%d\n,ptr2[-4],ptr2[-3],ptr2[-2],ptr2[-1]);

ptr3 = (char *)malloc(12);
i = (int *)(ptr3 - 4);
printf(\n ptr3 = %p,%d \n,ptr3,*i);
printf(\n %d:%d:%d:%d\n,ptr3[-4],ptr3[-3],ptr3[-2],ptr3[-1]);

ptr4 = (char *)malloc(12);
i = (int *)(ptr4 - 4);
printf(\n ptr4 = %p,%d \n,ptr4,*i);
printf(\n %d:%d:%d:%d\n,ptr4[-4],ptr4[-3],ptr4[-2],ptr4[-1]);

free(ptr1);
printf(\n ANALYZE-\n);
printf(\n %d:%d:%d:%d\n,ptr1[-4],ptr1[-3],ptr1[-2],ptr1[-1]);
printf(\n %d:%d:%d:%d\n,ptr1[0],ptr1[1],ptr1[2],ptr1[3]);
printf(\n %d:%d:%d:%d\n,ptr1[4],ptr1[5],ptr1[6],ptr1[7]);
printf(\n %d:%d:%d:%d\n,ptr1[8],ptr1[9],ptr1[10],ptr1[11]);

ptr = (char *)malloc(15);
i = (int *)(ptr - 4);
printf(\n ptr = %p,%d \n,ptr,*i);
return;
}


Thanks and Regards,
Shyamal




I'm not quite sure what it is you want to accomplish with this 
program.  However, malloc and free work on the program's given data 
area.  This data area can be increased should there be a need for more 
memory.


You should NEVER assume that memory blocks are contiguous.  There are many 
reasons why they would not be contiguous among them compiler 
optimizations.  If you really want to delve into how a program is executed, 
have the compiler output the assembler code and look at that.  The 
assembler code will show exactly how and where the variables are 
allocated.  With such small amount of data used in your program, it is 
possible the variables are all just on the stack.



You may want to check out the brk and sbrk man pages as they will give you 
some information into how memory management was originally done as these 
functions are lower-level than malloc and free.


-Derek

--
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.

___
freebsd-questions@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to [EMAIL PROTECTED]


memory allocation with malloc

2008-08-05 Thread Shyamal Shukla
Hi All,

 I am trying to validate my understanding of how malloc works by means
of the below C program which tries to corrupt essential information
maintained by malloc for free() operation.

The program allocates 4, 12 byte blocks (internally 16 bytes are allocated
for each 12 byte block). Hence the total allocated space was 48 bytes.

As malloc maintains the (length of allocated block + 1), 4 bytes before the
returned pointer (from malloc), I have manipulated this length for the first
block and set it to 49 with the goal that a single free shall release all
these 4 blocks and a subsequent malloc of 15 bytes shall be from the address
of first block.

However, this does not happen. Can someone please correct my understanding
and provide me with a reference to the working of malloc() and free()?

#includestdio.h

int main(void)
{
char * ptr,* ptr1, *ptr2, * ptr3, * ptr4;
int * i;
int n,q,p;
int loop = 0;

ptr1 = (char *)malloc(12);
i = (int *)(ptr1 - 4);
printf(\n ptr1 = %p,%d \n,ptr1,*i);
printf(\n %d:%d:%d:%d\n,ptr1[-4],ptr1[-3],ptr1[-2],ptr1[-1]);
printf(\n %d:%d:%d:%d\n,ptr1[0],ptr1[1],ptr1[2],ptr1[3]);
printf(\n %d:%d:%d:%d\n,ptr1[4],ptr1[5],ptr1[6],ptr1[7]);
printf(\n %d:%d:%d:%d\n,ptr1[8],ptr1[9],ptr1[10],ptr1[11]);
*i = 49;

ptr2 = (char *)malloc(12);
i = (int *)(ptr2 - 4);
printf(\n ptr2 = %p,%d \n,ptr2,*i);
printf(\n %d:%d:%d:%d\n,ptr2[-4],ptr2[-3],ptr2[-2],ptr2[-1]);

ptr3 = (char *)malloc(12);
i = (int *)(ptr3 - 4);
printf(\n ptr3 = %p,%d \n,ptr3,*i);
printf(\n %d:%d:%d:%d\n,ptr3[-4],ptr3[-3],ptr3[-2],ptr3[-1]);

ptr4 = (char *)malloc(12);
i = (int *)(ptr4 - 4);
printf(\n ptr4 = %p,%d \n,ptr4,*i);
printf(\n %d:%d:%d:%d\n,ptr4[-4],ptr4[-3],ptr4[-2],ptr4[-1]);

free(ptr1);
printf(\n ANALYZE-\n);
printf(\n %d:%d:%d:%d\n,ptr1[-4],ptr1[-3],ptr1[-2],ptr1[-1]);
printf(\n %d:%d:%d:%d\n,ptr1[0],ptr1[1],ptr1[2],ptr1[3]);
printf(\n %d:%d:%d:%d\n,ptr1[4],ptr1[5],ptr1[6],ptr1[7]);
printf(\n %d:%d:%d:%d\n,ptr1[8],ptr1[9],ptr1[10],ptr1[11]);

ptr = (char *)malloc(15);
i = (int *)(ptr - 4);
printf(\n ptr = %p,%d \n,ptr,*i);
return;
}


Thanks and Regards,
Shyamal



-- 
Linux - because life is too short for reboots...
___
freebsd-questions@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to [EMAIL PROTECTED]


Re: memory allocation with malloc

2008-08-05 Thread Giorgos Keramidas
On Tue, 5 Aug 2008 11:46:06 +0530, Shyamal Shukla [EMAIL PROTECTED] wrote:
 Hi All,

 I am trying to validate my understanding of how malloc works by means
 of the below C program which tries to corrupt essential information
 maintained by malloc for free() operation.

 The program allocates 4, 12 byte blocks (internally 16 bytes are allocated
 for each 12 byte block). Hence the total allocated space was 48 bytes.

 As malloc maintains the (length of allocated block + 1), 4 bytes before the
 returned pointer (from malloc), I have manipulated this length for the first
 block and set it to 49 with the goal that a single free shall release all
 these 4 blocks and a subsequent malloc of 15 bytes shall be from the address
 of first block.

 However, this does not happen. Can someone please correct my understanding
 and provide me with a reference to the working of malloc() and free()?

That's because the original assumption is false.  You wrote that malloc
maintains the (length of allocated block + 1), 4 bytes before the
returned pointer (from malloc).  But that is not really true for all
malloc() implementations, and it certainly isn't true for the `jemalloc'
implementation that FreeBSD 7.X and 8.0-CURRENT use.

___
freebsd-questions@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to [EMAIL PROTECTED]


Re: memory allocation with malloc

2008-08-05 Thread Giorgos Keramidas
On Tue, 05 Aug 2008 09:58:40 +0300, Giorgos Keramidas [EMAIL PROTECTED] wrote:
 On Tue, 5 Aug 2008 11:46:06 +0530, Shyamal Shukla [EMAIL PROTECTED] wrote:
 However, this does not happen. Can someone please correct my
 understanding and provide me with a reference to the working of
 malloc() and free()?

 That's because the original assumption is false.  [...]

I forgot to attach the link to the jemalloc paper, apologies.

Here it is:
http://people.freebsd.org/~jasone/jemalloc/bsdcan2006/jemalloc.pdf

This describes how jemalloc works.  This isn't a detailed line by line
walk-through of the source, but it should provide a good starting
point.  Then you can always read the source of BSD malloc() at:

  http://svn.freebsd.org/viewvc/base/head/lib/libc/stdlib/malloc.c?view=log

HTH,
Giorgos

___
freebsd-questions@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to [EMAIL PROTECTED]


Re: memory allocation/deallocation (malloc experts needed)

2004-05-21 Thread Till Plewe
On Thu, May 20, 2004 at 05:36:31PM +0900, Charlie Root wrote:
 On Thu, May 20, 2004 at 01:42:00AM -0500, Dan Nelson wrote:
  In the last episode (May 20), Till Plewe said:
   My problem is essentially that freeing large numbers of small chunks
   of memory can be very slow. I have run into this problem twice so
   far.
  
  Do you have a testcase?  The attached program mallocs 1 million
  128-byte blocks, then frees them.  With MALLOC_OPTIONS set to jz (i.e.
  no filling of freed memory), it takes .184 seconds to free them all. 
  With it set to J, it takes 1 second.
  
  CPU: Intel Pentium III (909.96-MHz 686-class CPU)
   
 
 ...

I changed your program a little bit to allow freeing the memory in
random order which is closer to what happens when hash tables are
deleted. The test program now allocates NUM pointers to SIZE byte
memory chunks and then frees them.  RANDOM 0 means the order in which
the items are freed is the same as the order of allocation, while
RANDOM 1 means that the memory is freed in (somewhat) random order
The data below shows that freeing the memory is the bottleneck. 
(MALLOC_OPTIONS JZ, using jz gives essentially the same results perhaps
about 25% faster)

My current guess is that the part copied below of the function
free_bytes in /usr/src/lib/libc/stdlib/malloc.c is to blame
where linked lists are traversed to move/delete pages whose
status has changed. At least that would explain the quadratic
behaviour in the output of the test program below.   
 

lines 1010-1028 of /usr/src/lib/libc/stdlib/malloc.c

if (info-free == 1) {

/* Page became non-full */

mp = page_dir + info-shift;
/* Insert in address order */
while (*mp  (*mp)-next  (*mp)-next-page  info-page)
mp = (*mp)-next;
info-next = *mp;
*mp = info;
return;
}

if (info-free != info-total)
return;

/* Find  remove this page in the queue */
while (*mp != info) {
mp = ((*mp)-next);
==


FreeBSD 5.2-CURRENT Sun May  2 08:40:29 JST 2004
CPU: Intel(R) Xeon(TM) CPU 2.40GHz (2392.05-MHz 686-class CPU)

test -n 20
NUM 120 RANDOM 0 SIZE 16  malloc: 0.140976  free: 0.113800
NUM 120 RANDOM 1 SIZE 16  malloc: 0.153176  free: 1.671878
test -n 21
NUM 121 RANDOM 0 SIZE 16  malloc: 0.277667  free: 0.228911
NUM 121 RANDOM 1 SIZE 16  malloc: 0.320030  free: 5.991513
test -n 22
NUM 122 RANDOM 0 SIZE 16  malloc: 0.492440  free: 0.466889
NUM 122 RANDOM 1 SIZE 16  malloc: 0.591442  free: 22.437910
test -n 23
NUM 123 RANDOM 0 SIZE 16  malloc: 1.106733  free: 0.929016
NUM 123 RANDOM 1 SIZE 16  malloc: 1.180094  free: 86.868541
test -n 24
NUM 124 RANDOM 0 SIZE 16  malloc: 2.040155  free: 1.866336
NUM 124 RANDOM 1 SIZE 16  malloc: 2.250588  free: 356.746455
test -n 25
NUM 125 RANDOM 0 SIZE 16  malloc: 4.280042  free: 3.716874
NUM 125 RANDOM 1 SIZE 16  malloc: 4.567206  free: 1497.213212
test -n 26
NUM 126 RANDOM 0 SIZE 16  malloc: 8.543537  free: 7.612657
NUM 126 RANDOM 1 SIZE 16  malloc: 9.055712  free: 6187.992730


==
FreeBSD 5.2-CURRENT Wed May 19 10:59:08 JST 2004
CPU: AMD Opteron(tm) Processor 248 (2205.01-MHz K8-class CPU)

test -n 20 
NUM 120 RANDOM 0 SIZE 16  malloc:0.124275  free:0.067746
NUM 120 RANDOM 0 SIZE 16  malloc:0.098449  free:0.066730
NUM 120 RANDOM 1 SIZE 16  malloc:0.119348  free:1.435530
NUM 120 RANDOM 1 SIZE 16  malloc:0.099841  free:1.428259
test -n 21 
NUM 121 RANDOM 0 SIZE 16  malloc:0.213471  free:0.134132
NUM 121 RANDOM 0 SIZE 16  malloc:0.199287  free:0.132293
NUM 121 RANDOM 1 SIZE 16  malloc:0.184251  free:4.998957
NUM 121 RANDOM 1 SIZE 16  malloc:0.186739  free:4.849894
test -n 22 
NUM 122 RANDOM 0 SIZE 16  malloc:0.464616  free:0.255515
NUM 122 RANDOM 0 SIZE 16  malloc:0.425375  free:0.254138
NUM 122 RANDOM 1 SIZE 16  malloc:0.404901  free:17.264623
NUM 122 RANDOM 1 SIZE 16  malloc:0.394420  free:18.328755
test -n 23 
NUM 123 RANDOM 0 SIZE 16  malloc:0.819199  free:0.514065
NUM 123 RANDOM 0 SIZE 16  malloc:0.858903  free:0.520739
NUM 123 RANDOM 1 SIZE 16  malloc:0.830438  free:67.556339
NUM 123 RANDOM 1 SIZE 16  malloc:0.821419  free:67.287440
test -n 24 
NUM 124 RANDOM 0 SIZE 16  malloc:1.726636  free:1.032238
NUM 124 RANDOM 0 SIZE 16  malloc:1.709127  free:1.028701
NUM 124 RANDOM 1 SIZE 16  malloc:1.615758  free:290.153962
NUM 124 RANDOM 1 SIZE 16  malloc:1.645739  free:279.887830
test -n 25 
NUM 125 RANDOM 0 SIZE 16  malloc:3.429280  free:2.044097
NUM 125 RANDOM 0 SIZE 16  malloc:3.486703  free:2.026912
NUM 125 RANDOM 1 SIZE 16  malloc:3.536784  free:1172.642691
NUM 125 RANDOM 1 SIZE 16  malloc:3.481226  free:1176.604815


==
test program

#include stdio.h   
#include stdlib.h  
#include sys/time.h 

Re: memory allocation/deallocation (malloc experts needed)

2004-05-21 Thread Till Plewe
On Thu, May 20, 2004 at 09:28:12AM -0400, Chuck Swiger wrote:
 Till Plewe wrote:
 My problem is essentially that freeing large numbers of small chunks
 of memory can be very slow. I have run into this problem twice so far.
 [ ... ]
 One solution would be to divide the memory in larger regions and to
 tell malloc which chunk to use for the next few calls, respectively when a
 whole chunk could be freed. But I don't know how to do this.
 
 Consider using (or searching for information about) a zone-based malloc. 
 NEXTSTEP used one and hence Darwin/OS X probably have sources available for 
 you to consider...
 

Thanks. I will give it a try. Although I was hoping to find somebody who 
has already an alternative malloc implementation running.

- Till

___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to [EMAIL PROTECTED]


Re: memory allocation/deallocation (malloc experts needed)

2004-05-20 Thread Dan Nelson
In the last episode (May 20), Till Plewe said:
 My problem is essentially that freeing large numbers of small chunks
 of memory can be very slow. I have run into this problem twice so
 far.

Do you have a testcase?  The attached program mallocs 1 million
128-byte blocks, then frees them.  With MALLOC_OPTIONS set to jz (i.e.
no filling of freed memory), it takes .184 seconds to free them all. 
With it set to J, it takes 1 second.

CPU: Intel Pentium III (909.96-MHz 686-class CPU)
 
-- 
Dan Nelson
[EMAIL PROTECTED]
#include stdio.h
#include stdlib.h
#include sys/time.h
#include sys/resource.h

#define NUM 1048576
#define SIZE 128

void *mypointers[NUM];
struct timeval elap;
struct rusage r_s, r_e;

int main(void)
{
int i;

printf(malloc:);
fflush(stdout);
for (i = 0; i  NUM; i++)
{
mypointers[i] = malloc(SIZE);
}
printf(done.\nfree:);
fflush(stdout);
getrusage(RUSAGE_SELF, r_s);
for (i = 0; i  NUM; i++)
{
free(mypointers[i]);
}
getrusage(RUSAGE_SELF, r_e);
timersub(r_e.ru_utime, r_s.ru_utime, elap);
printf(done. %ld.%06ld\n, elap.tv_sec, elap.tv_usec);
return 0;
}
___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to [EMAIL PROTECTED]


Re: memory allocation/deallocation (malloc experts needed)

2004-05-20 Thread Charlie Root
On Thu, May 20, 2004 at 01:42:00AM -0500, Dan Nelson wrote:
 In the last episode (May 20), Till Plewe said:
  My problem is essentially that freeing large numbers of small chunks
  of memory can be very slow. I have run into this problem twice so
  far.
 
 Do you have a testcase?  The attached program mallocs 1 million
 128-byte blocks, then frees them.  With MALLOC_OPTIONS set to jz (i.e.
 no filling of freed memory), it takes .184 seconds to free them all. 
 With it set to J, it takes 1 second.
 
 CPU: Intel Pentium III (909.96-MHz 686-class CPU)
  

...

I get 

NUM SIZEMALLOC_OPTIONS  time
1058576 128 jz  0.044
1058576 128 JZ  0.13

128*1048576 8   jz  5.28
128*1048576 8   JZ  7.70

200*1048576 8   jz  8.25
200*1048576 8   JZ  13.17   

with CPU: AMD Opteron(tm) Processor 248 (2205.02-MHz K8-class CPU)

but with NUM 255*1048576 I run out of memory (although I have 6GB and
your test program should only use about
(sizeof(void*)+SIZE)*NUM=(8+8)*255*1048576=4GB)

Using NUM 256*1048576, SIZE 8 I get 

# gcc -o test test.c
/var/tmp//ccLxywz6.s: Assembler messages:
/var/tmp//ccLxywz6.s:95: Error: .COMMon length (-2147483648.) 0! Ignored.
/var/tmp//ccLxywz6.s:95: Warning: rest of line ignored; first ignored character is `,'

In any case since I have the pointers in a hash table (Judy array)
rather than an array I need extra time for look-up/deleting the entry
in the hash table as well. If I could get malloc to use a fixed memory
region for the part I want to delete (both for the hash table and the
information pointed to) deletion should take no time at all.

In my program I get times like this 

DATA 6.553015 sec 
JUDY 7.593997 sec
deleted 1272062 hash entries, freed 28542840(Judy) + 15264744(data) bytes 

where judy translates hash values to pointers pointing to simple structs. 
Since I want to delete up to 10^8 entries the times get quite bad.
 
I guess quite a bit of the extra time is spent jumping around in
memory. Your test program frees memory in the order it was allocated which
should be a quite regular pattern. 

I will test some more and then post some more details.
Thanks for your answer.

- Till

___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to [EMAIL PROTECTED]


Re: memory allocation/deallocation (malloc experts needed)

2004-05-20 Thread Chuck Swiger
Till Plewe wrote:
My problem is essentially that freeing large numbers of small chunks
of memory can be very slow. I have run into this problem twice so far.
[ ... ]
One solution would be to divide the memory in larger regions and to
tell malloc which chunk to use for the next few calls, respectively when a
whole chunk could be freed. But I don't know how to do this.
Consider using (or searching for information about) a zone-based malloc. 
NEXTSTEP used one and hence Darwin/OS X probably have sources available for 
you to consider...

--
-Chuck
___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to [EMAIL PROTECTED]


memory allocation/deallocation (malloc experts needed)

2004-05-19 Thread Till Plewe
My problem is essentially that freeing large numbers of small chunks
of memory can be very slow. I have run into this problem twice so far.

1) Shutting down python can take several minutes if I have used large
dictionaries. The solution I use here is to exit python without
freeing the allocated memory (not really a good solution).

2) Freeing large hashtables in C. (No solution yet.)

For these hashtables I can fairly easily divide the data into groups
which could be deleted together. If I have all this data in one
predefined region of memory then deleting them would be very
fast. However in order to keep memory consumption as low as possible
without sacrificing speed I am using Judy arrays (see the Judy project
at source forge). But that means I have no direct control over how
malloc is called.

One solution would be to divide the memory in larger regions and to
tell malloc which chunk to use for the next few calls, respectively when a
whole chunk could be freed. But I don't know how to do this.

Cyclone's regions seem to provide more or less what I need but cyclone
works on neither CURRENT nor on amd64. 

Any suggestions where to look/what to read are greatly appreciated 

- Till


___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to [EMAIL PROTECTED]