|
List Info
Thread: silly question about swap, malloc and physical memory limits...
|
|
| silly question about swap, malloc and
physical memory limits... |

|
2007-08-13 08:06:03 |
Hi all,
I think I am doing something wrong here so sorry for
probably wasting
your time on this one... Is it a
prerequisite to have a swap
enabled in OpenBSD? I am running without any swap being
setup on my
system and there appears to be a problem with malloc
(OpenBSD 4.1,
iBook G4)...
There is a total of 256Meg RAM on my machine, but because
kernel and
other stuff occupy some memory, I would expect that there
should be
less than the total phys-mem available for a user-spaced
program
trying to do some malloc(ing) (keeping in mind there is no
swap).
However, not only the total phys-mem is allocatable via
malloc (in the
below sample code), it even allocates what is clearly
greater than
total phys-mem available.
The following code (e.g. compiled with gcc main.cc -lstdc++
-lm):
#include <sys/param.h>
#include <sys/sysctl.h>
#include <iostream>
using namespace std;
int main ()
{
int mib[] = {CTL_HW, HW_PHYSMEM}, ram;
size_t len (sizeof (ram));
if (sysctl (mib, 2, &ram, &len, NULL, 0) != -1
&& ram > 0)
{
cout << "system's RAM is: " << ram
<< endl;
ram += 270000000;
void *availableRam;
while ( (availableRam = malloc (ram)) == NULL &&
--ram);
if (availableRam != NULL)
{
cout << "have allocated " << ram
<< endl;
free (availableRam);
}
else
cerr << "could not allocate any bytes"
<< endl;
}
else
cerr << "sysctl could not get the system's RAM
size" << endl;;
return 0;
}
Produces the following output when running on iBook G4, no
swap
available and with /dev/wd0a as the only partition (i.e. no
wd0b,
etc.):
system's RAM is: 268435456
have allocated 536141815
Even when commenting out the
ram += 270000000;
line, the malloc should not be able to get the whole
phys-mem
amount... me thinks?
Stressing the issue a little further... writing data to the
allocated
memory (i.e. byte by byte) appears to at times either result
in
seg-fault or completely freezing the machine (I am runnig
the
aforementioned code as root).
I am sure I am missing something this time
Kind regards
Leon.
|
|
| Re: silly question about swap, malloc
and physical memory limits... |

|
2007-08-14 01:18:27 |
2007/8/13, leon zadorin <leonleon77 gmail.com>:
> Hi all,
>
> I think I am doing something wrong here so sorry for
probably wasting
> your time on this one... Is it a
prerequisite to have a swap
> enabled in OpenBSD? I am running without any swap
being setup on my
> system and there appears to be a problem with malloc
(OpenBSD 4.1,
> iBook G4)...
>
> There is a total of 256Meg RAM on my machine, but
because kernel and
> other stuff occupy some memory, I would expect that
there should be
> less than the total phys-mem available for a
user-spaced program
> trying to do some malloc(ing) (keeping in mind there is
no swap).
When you malloc() memory the, kernel does not actually
reserve pages.
It sets up mappings so that on the first access, a page is
reserved.
I am not really certain what checks are performed by the
kernel
allocator, but apparently nothing about total availible
memory.
> However, not only the total phys-mem is allocatable via
malloc (in the
> below sample code), it even allocates what is clearly
greater than
> total phys-mem available.
>
> The following code (e.g. compiled with gcc main.cc
-lstdc++ -lm):
>
> #include <sys/param.h>
> #include <sys/sysctl.h>
> #include <iostream>
>
> using namespace std;
>
> int main ()
> {
> int mib[] = {CTL_HW, HW_PHYSMEM}, ram;
> size_t len (sizeof (ram));
> if (sysctl (mib, 2, &ram, &len, NULL,
0) != -1 && ram > 0)
> {
> cout << "system's RAM is:
" << ram << endl;
> ram += 270000000;
> void *availableRam;
> while ( (availableRam = malloc (ram))
== NULL && --ram);
> if (availableRam != NULL)
> {
> cout << "have
allocated " << ram << endl;
> free (availableRam);
> }
> else
> cerr << "could not
allocate any bytes" << endl;
> }
> else
> cerr << "sysctl could not
get the system's RAM size" << endl;;
> return 0;
> }
>
> Produces the following output when running on iBook G4,
no swap
> available and with /dev/wd0a as the only partition
(i.e. no wd0b,
> etc.):
>
> system's RAM is: 268435456
> have allocated 536141815
>
>
> Even when commenting out the
> ram += 270000000;
> line, the malloc should not be able to get the whole
phys-mem
> amount... me thinks?
>
> Stressing the issue a little further... writing data to
the allocated
> memory (i.e. byte by byte) appears to at times either
result in
> seg-fault or completely freezing the machine (I am
runnig the
> aforementioned code as root).
The segfault is most probably caused by an access for which
the kernel
cannot find a free page. The hangs can also be attributed
to that.
UNIX in general is not really forgiving when there is no
memory left.
That's why a swap device is recommended.
> I am sure I am missing something this time
>
> Kind regards
> Leon.
>
>
--
La brigade SnW est au rayon des surgelC)s
|
|
| Re: silly question about swap, malloc
and physical memory limits... |

|
2007-08-14 06:14:12 |
On 8/14/07, Arnaud Bergeron <abergeron gmail.com> wrote:
> When you malloc() memory the, kernel does not actually
reserve pages.
> It sets up mappings so that on the first access, a page
is reserved.
> I am not really certain what checks are performed by
the kernel
> allocator, but apparently nothing about total availible
memory.
Very interesting
The max limit that malloc will honor is as per "ulimit
-d" and appears
to max out at twice the RAM size, so this would appear that
having
swap would help... but it certainly would not solve the
"problem" -
the "ulimit -d" applies individually to each
process (so one could
start 100 processes, each running at the same time and
mallocing a
total of > RAM + swap)...
In short, it appears to be very close to the following
(albeit dated)
thingy in LInux:
http://list.coin-or.org/pipermail/coin
-lpsolver/2005-September/000354.html
"
Here is a snippet from "man malloc"
describing the issue:
BUGS
By default, Linux follows an optimistic memory
allocation
strategy. This means that when malloc() returns non-NULL
there is
no guarantee that the memory really is available. This is
a really
bad bug. In case it turns out that the system is out of
memory, one
or more processes will be killed by the infamous OOM killer.
In case
Linux is employed under circumstances where it would be
less
desirable to suddenly lose some randomly picked
processes, and
moreover the kernel version is sufficiently recent, one can
switch
off this overcommitting behavior using a command like
# echo 2 > /proc/sys/vm/overcommit_memory
"
Is there such/similar "no overcommit" thing in
OpenBSD? I have looked
(cursively) into uvm_mmap and played with extending the
check for
ulimit, in sys_mmap:
"
if ((flags & MAP_ANON) != 0 ||
((flags & MAP_PRIVATE) != 0 && (prot
& PROT_WRITE) != 0)) {
if (size >
(p->p_rlimit[RLIMIT_DATA].rlim_cur -
ctob(p->p_vmspace->vm_dused))) {
error = ENOMEM;
goto out;
}
}
"
with the use of uvmexp.free, npages, swpages, etc. - and
whilst it
honors the RAM/swap sizes, it obviously does not recognize
the total
"SIZE" of every running process (only the resident
size...) and of
course, the subsequent "swapctl -d" would need to
block or error if
some pages would need to be swapped back into RAM and there
was not
enough room... anyway, I will try running as non-root with
the default
"return non-null from malloc even on sizes that are
known to be too
large for the total memory available on system", and
for as long as
the proces just segfaults and not freezes the box - I think
it will do
|
|
| Re: silly question about swap, malloc
and physical memory limits... |

|
2007-08-14 08:32:04 |
On 8/14/07, leon zadorin <leonleon77 gmail.com> wrote:
> On 8/14/07, Arnaud Bergeron <abergeron gmail.com> wrote:
>
> > When you malloc() memory the, kernel does not
actually reserve pages.
> > It sets up mappings so that on the first access, a
page is reserved.
> > I am not really certain what checks are performed
by the kernel
> > allocator, but apparently nothing about total
availible memory.
>
> Very interesting
>
...
> ... anyway, I will try running as non-root with the
default
> "return non-null from malloc even on sizes that
are known to be too
> large for the total memory available on system",
and for as long as
> the proces just segfaults and not freezes the box - I
think it will do
>
I am not sure if I should be getting worried here, but... it
would
appear that I am able to run as *average* user and still
*freeze* the
whole system (the keyboard does not respond when in
command-line mode
and, when running from within X, mouse is also freezing)...
This happens either when the system runs without any swap or
with swap
(enabled/added via swapon ./someFile)...
The freeze is reproducable on my machine (iBook G4, 1.2GHz,
256Meg
RAM, OpenBSD 4.1 and the swapon enables the 500Meg swap
file) by
running multiple instances of the program, e.g.
./a.out &
./a.out &
./a.out &
./a.out &
./a.out &
either from login shell (in command-line) or from xterm (in
X)...
If it is of any relevance - my disk layout does not have
wd0b
partition (i.e. only 1 partition, wd0a mounted as /) ....
Anyway, I would be VERY interested if others are able to
reproduce the
"freeze" problem (the thing that concerns me most
is that when the
aforementioned scenario is being performed by an average
user the
things do not seg-fault/etc., but rather have a
"freezing" effect on
the system...) The only exception to the
"freezing" effect was that I
could still press "F1/F2" on iBook and get the
"brightness change"
effect in LCD display (I have tried it when in
command-line)... but I
don't know which part of kernel (if any) manages this
functionality,
etc.
The following code was compiled as
gcc ./test.cc -lstdc++ -lm
#include <sys/param.h>
#include <sys/sysctl.h>
#include <iostream>
using namespace std;
int main ()
{
int mib[] = {CTL_HW, HW_PHYSMEM}, ram;
size_t len (sizeof (ram));
if (sysctl (mib, 2, &ram, &len, NULL, 0) != -1
&& ram > 0)
{
cout << "system's RAM is: " << ram
<< endl;
void *availableRam;
while ( (availableRam = malloc (ram)) == NULL &&
--ram);
if (availableRam != NULL)
{
cout << "have allocated " << ram
<< endl;
char * iteratorByte (static_cast<char *>
(availableRam));
for (int i (0); i < ram; ++i)
{
*iteratorByte = 0;
++iteratorByte;
}
free (availableRam);
}
else
cerr << "could not allocate any bytes"
<< endl;
}
else
cerr << "sysctl could not get the system's RAM
size" << endl;;
return 0;
}
Thanks to everyone, by the way, for the time they take to
read my
silly messages
|
|
[1-4]
|
|