From: Dennis Hoppe on
Hi,

my machine has 4 GB of RAM and I am wondering, why I can't use
at least 2 or 3 GBytes to run an Ada program. It seems, that my
Ada Compiler (Gnat 4.4.0) limit the memory to 2 GB per default.
Is it possible to allocate more than 2 GB?

Here is a simple example of an "evil" vector, that gains
more memory in each pass. The program terminates exactly at
1024 MB of used Heap memory.


with Ada.Containers.Vectors;

procedure Heap is
package Generic_Vector is new Ada.Containers.Vectors
(Element_Type => Integer, Index_Type => Natural);

Evil_Vector : Generic_Vector.Vector;
begin -- Heap
loop
Generic_Vector.Append (Evil_Vector, Integer'Last);
end loop;
end Heap;


heap(6374) malloc: *** mmap(size=2147487744) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug

raised STORAGE_ERROR : heap exhausted


I could not find a suitable Compiler switch or a parameter, that
can be set for the operating system (linux). "ulimit -v" is already
set to unlimited.

"gnatmem" reports, that my water mark with 1024 MB is reached, but
the final water mark is, needless to say, higher.


Best regards,
Dennis Hoppe
From: Adam Beneschan on
On Jun 24, 1:44 am, Dennis Hoppe <dennis.ho...(a)hoppinet.de> wrote:
> Hi,
>
> my machine has 4 GB of RAM and I am wondering, why I can't use
> at least 2 or 3 GBytes to run an Ada program.

Well, if you were using Windows, I'd guess this is because Windows
reserves about 3.98 GB of your RAM for itself. But I notice that you
said further on down that you were using Linux, so the heck with that
answer........

> It seems, that my
> Ada Compiler (Gnat 4.4.0) limit the memory to 2 GB per default.
> Is it possible to allocate more than 2 GB?

I don't know GNAT intimately, and I don't work on it. But 2 GB =
2**31 bytes, and the largest possible value of a signed 32-bit integer
is 2**31-1. So if their runtime is using 32-bit integers to hold
values like that, there may be no way to deal with larger memory
amounts without a rewrite of the runtime.

-- Adam
From: Robert A Duff on
Dennis Hoppe <dennis.hoppe(a)hoppinet.de> writes:

> my machine has 4 GB of RAM and I am wondering, why I can't use
> at least 2 or 3 GBytes to run an Ada program. ...

I don't think this has anything to do with Ada or GNAT.
It's an OS issue. You could verify that by writing
a similar memory-eating program in some other language,
like C.

I had a similar problem a while ago, where the OS was reserving 2GB of
the address space for itself, by default. But there was an option
to decrease that to 1GB, leaving 3GB for the user-mode program.
I don't remember if I did that on windows or linux (or both).

So check if there is such an option on linux.

Anyway, if you're getting that close to the hardware limit of 4GB,
it's probably time to upgrade to a 64-bit machine (and OS)!

- Bob
From: Peter Schildmann on
Dennis Hoppe schrieb:
> loop
> Generic_Vector.Append (Evil_Vector, Integer'Last);
> end loop;

It's not a good idea to use the STORAGE_ERROR exception
to terminate an endless loop.

This should work:

with Ada.Text_IO;
with Ada.Containers;
with Ada.Containers.Vectors;

procedure Heap is

package Cnt_IO is new Ada.Text_IO.Integer_IO
(Ada.Containers.Count_Type);

package Generic_Vector is new Ada.Containers.Vectors
(Element_Type => Integer, Index_Type => Natural);

Evil_Vector : Generic_Vector.Vector;

Size : constant := Integer'Size / Standard'Storage_Unit;

begin

for N in 0 .. Natural'Last / Size loop
Generic_Vector.Append (Evil_Vector, N);
end loop;

Cnt_IO.Put (Generic_Vector.Capacity (Evil_Vector));

end Heap;


- Peter
From: Gene on
On Jun 24, 4:44 am, Dennis Hoppe <dennis.ho...(a)hoppinet.de> wrote:
> Hi,
>
> my machine has 4 GB of RAM and I am wondering, why I can't use
> at least 2 or 3 GBytes to run an Ada program. It seems, that my
> Ada Compiler (Gnat 4.4.0) limit the memory to 2 GB per default.
> Is it possible to allocate more than 2 GB?
>
> Here is a simple example of an "evil" vector, that gains
> more memory in each pass. The program terminates exactly at
> 1024 MB of used Heap memory.
>
> with Ada.Containers.Vectors;
>
> procedure Heap is
>    package Generic_Vector is new Ada.Containers.Vectors
>      (Element_Type => Integer, Index_Type => Natural);
>
>    Evil_Vector : Generic_Vector.Vector;
> begin -- Heap
>    loop
>      Generic_Vector.Append (Evil_Vector, Integer'Last);
>    end loop;
> end Heap;
>
> heap(6374) malloc: *** mmap(size=2147487744) failed (error code=12)
> *** error: can't allocate region
> *** set a breakpoint in malloc_error_break to debug
>
> raised STORAGE_ERROR : heap exhausted
>
> I could not find a suitable Compiler switch or a parameter, that
> can be set for the operating system (linux). "ulimit -v" is already
> set to unlimited.
>
> "gnatmem" reports, that my water mark with 1024 MB is reached, but
> the final water mark is, needless to say, higher.
>

Your code thrashes the heap pretty hard. Containers doubles the size
of the vector's internal array each time it runs out. So the 2Gb
request means 1Gb is already in use. Dont' know about your malloc(),
but it's easy to see that a 1Gb allocated block in a 4Gb arena can
preclude a further 2Gb allocation.

What happens if call Reserve_Capacity(a, Natural'Last) at the
beginning?

 |  Next  |  Last
Pages: 1 2 3
Prev: GNAT.Serial_Communications ?
Next: Larger matrices