Prev: GNAT.Serial_Communications ?
Next: Larger matrices
From: Dennis Hoppe on 24 Jun 2008 04:44 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 24 Jun 2008 11:03 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 24 Jun 2008 13:32 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 24 Jun 2008 14:55 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 24 Jun 2008 16:03
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? |