Home c++ Memory fragmentation

Memory fragmentation

Author

Date

Category

As you know, the garbage collector in C # (more precisely, in CLR) spends cleaning of RAM, freeing the memory occupied by variables that are no longer used. In addition, it also produces memory defragmentation, “sealing” bunch.

In this regard, there is a correction of links to objects that survived the garbage collection. Probably something similar happens when assembling garbage and in other languages.

in C++ there is no garbage collector. In this case, even if the programmer does not forget to clear all the memory allocated earlier, it still may not be enough due to fragmentation, since the defragmentation process is not carried out.

That is, a paradoxical situation is possible when the total size of free memory is greater than is required to create a new object, but the object cannot be created.
Is it so? There is a feeling that I am mistaken in my arguments, but where?


1, Authority 100%

The question is very good. And the topic is interesting and important. However, it seems to me (maybe it seems simple) that you confuse two things, more precisely, two levels of memory fragmentation. Memory can be fragmented at the level of physical memory. In systems with a virtual memory model (and there are now the overwhelming majority) this is not a problem, since even a strongly fragmented real memory will be simply proprietary to the sequential virtual address space of the process.

Another thing if fragmentation occurs at the virtual memory level. This can easily occur in programs on C or C++, where numerous allocations and removal of small memory fragments occur. This can lead to a strong memory leakage (although the code all selected memory is released!) And, perhaps, to the exhaustion of all system memory. But here, Cerdyk will come to everything, if the system does not track such situations and does not unload “voracious” processes.


2, Authority 81%

Yes, this is possible. And often arises in loaded applications.

To solve this situation there are many solutions. For example, custom allocators. Suppose in the application you need to allocate many times the memory for small objects. Custom allocator highlights a slightly larger memory (rounded to multiple 2 to the degree). The allocator during the start highlights one large amount of memory and breaks it to the sections for 2B8, for 2B10 (and so on). With the correct approach, the allocator although it will spend more memory, but there will be no fragmentation. The destructor does not unlock the memory of the system back, but simply marks as free.


3, Authority 42%

The question for some reason again caused interest. Here I took and tried. It is always nice to learn something new.

Short Report:

It turned out that in Ubunt, if the Soft Limit is not installed, then instead of the expected Enomem we get SIGKILL from the kernel .

on a 64-bit virtual rza gig and 2.5 gigami swop with malloc (1000) This process lasts only 1.5 minutes !!! (So ​​we assume that I just joked, claiming “that so long do not live”).

After installing the limit on virtual memory (800 megs), Malloc began to return 0 and I checked the question of fragmentation.

Indeed, freeing the 80 megs of the realloc-ohm “on the place” (reducing each block by 100 bytes), could not allocate 1000 bytes of the Malloc-Ohm, and 50 bytes managed to get how it was not difficult Guess, only half of the previously liberated memory.

(if a test program is interesting to someone, then write, tomorrow I will insert in addition to the answer. )


(probably better late than ever -))

/ * https://drive.google.com/file/d/0bzy1lbmzngbwbuytns01vwvxug8/view?usp=sharing
 Show Memory Fragmentation
 USE ULIMIT -A FOR LOOK LIMITS
 ULIMIT -S -V NNNNN FOR SEE MALLOC RETURNS 0 AND TRYALOC SHOW
 Or.
 ULIMIT -S -V UNLIMITED FOR SIGKILL IF NO MORE MEMORY
 * /
#Include & lt; stdio.h & gt;
#Include & lt; stdlib.h & gt;
#Include & lt; stdint.h & gt;
#Include & lt; limits.h & gt;
#Include & lt; String.h & gt;
#Include & lt; Signal.h & gt;
#Include & lt; errno.h & gt;
#Include & lt; setJmp.h & gt;
#Include & lt; sys / sysinfo.h & gt;
#Include & lt; unistd.h & gt; 
#Include & lt; sys / wait.h & gt;
#Include & lt; Time.h & gt;
struct memblk {
 STRUCT MEMBLK * NEXT;
 Size_t MBSIZE;
 Char D [];
};
STRUCT DATA {
 void * addr;
 Size_t NB;
};
#Define M1 (1024 * 1024)
#ifndef swap_bound
#Define swap_bound 10
/ * When we choose the whole Freeram and FreesWap (values ​​when starting the program)
  In addition to swap_bound SWAP share (for example, 50 is 1 / 50th),
  We start SATING DATA ON MEED MEDICATION PAYPE FOR PRINT
  Final results
  (since here already at any time can get SIGKILL from the nucleus)
* /
#Endif
SigJMP_BUF JMP;
int signo = 0;
Void.
Catch (int sig)
{
 Signo = Sig;
 SiglongJMP (JMP, SIG);
}
/ *
 Time in milliseconds
 * /
Static Long Long.
MTIME ()
{
 STRUCT TIMEVAL T;
 GetTimeOFDay (& amp; t, null);
 Long Long MT = (Long Long) T.TV_SEC * 1000 + T.TV_USEC / 1000;
 Return MT;
}
int.
Main (Int AC, char * AV [])
{
 Size_t MBSIZE = AV [1]? ATOI (AV [1]): 1000,
  N1000 = 0, S1000 = 0;
 STRUCT MEMBLK * L1000 = 0,
  * p;
 STRUCT SYSINFO INFO;
 sysinfo (& amp; info);
 PrintF ("Total (Free) RAM:% LD (% LD) Total (Free) SWAP:% LD (% LD) (in% d units) \ n",
   info.totalram, info.foram, info.totalswap, info.freeswap,
   info.mem_unit);
 INT CHAN [2];
 PIPE (CHAN);
 STRUCT DATA TR = {0};
 Long Long Start = MTime ();
 PID_T CHILD;
 if (child = fork ()) {
  Close (CHAN [1]);
  INT S, CRIT = 0;
  While (Read (Chan [0], & amp; TR, SizeOF (TR)) == SizeOF (TR))
   CRIT ++;
  PID_T P = WAIT (& amp; s);
  if (crit)
   PrintF ("Fin% D Critical Blocks \ N"
     "Total% LD Blocks% LD Bytes (% F Mb)% LLD MSEC \ N"
     Crit
     (long) tr.nb, (Long) (tr.nb * MBSIZE),
     ((Double) (TR.NB * MBSIZE)) / M1, MTIME () - START);
  ELSE.
   PrintF ("No Final Critical Data% LLD MSEC \ N", Mtime () - Start);
  if (p == child)
   if (Wifexited (s))
  EXIT (Wexitstatus (S));
   ELSE.
  RAISE (Wtermsig (S));
  RETURN PUTS ("UNEXEPCTED EXIT");
 }
 int sig;
 FOR (SIG = 1; SIG & LT; 64; SIG ++)
  If (Signal (Sig, Catch) == Sig_err)
   printf ("Err Signo% d \ n", Sig);
 If (Sig = SigsetJMP (JMP, 0)) {
  PrintF ("Catch Sig% D (Signo% d) \ n",
    SIG, SIGNO);
  EXIT (0);
 }
 int done = 0;
 While (P = (Typeof (P)) Malloc (MBSIZE)) {
  P- & GT; MBSIZE = MBSIZE;
  p- & gt; next = L1000;
  L1000 = P;
  N1000 ++;
  S1000 + = MBSIZE;
  if (n1000% m1 == 0)
   PrintF ("% LD Blocks% LD Bytes (% F Mb)% LLD MSEC \ N",
     (long) N1000, (Long) S1000, ((Double) S1000) / M1, MTIME () - START);
  ELSE If (N1000 * MBSIZE & GT; info.foram * info.mem_unit + info.foeswap * info.mem_unit - info.foeswap * info.mem_unit / swap_bound) {
   TR.NB = N1000;
   tr.addr = p;
   Write (Chan [1], & amp; TR, Sizeof (TR));
   If (! Done)
  Done = 1, PrintF ("Begin Crit:% LD \ N", (long) tr.nb);
  }
 }
 PrintF ("End% LD Blocks% LD Bytes (% F Mb)% LLD MSEC \ N",
   (long) N1000, (Long) S1000, ((Double) S1000) / M1, MTIME () - START);
 Close (CHAN [0]);
 Close (CHAN [1]);
 if (p = malloc (5))
  Puts ("Malloc (5) Yes");
 PrintF ("Malloc (50)% s \ n", Malloc (50)? "Yes": "No");
 Typeof (P) Prev = 0, T;
 Size_t SAVE = 0, D = MBSIZE / 10;
 START = MTIME ();
 For (p = l1000; p; p = p- & gt; next) {
  if (t = realloc (p, p- & gt; mbsize - d)) {
   T- & GT; MBSIZE - = D;
   IF (T! = P) {
  PUTS ("NEW ADDR");
  if (prev)
   prev- & gt; next = t;
  ELSE.
   L1000 = T;
   }
   Prev = P = T;
   SAVE + = D;
  } else {
   PUTS ("CAN'T REALLOC");
   EXIT (1);
  }
 }
 Printf ("Realloc D:% LD SUM:% LD (% LLD MSEC) \ n",
   (long) d, (long) save, mtime () - start);
 PrintF ("Malloc (1000) Again:% S \ N", Malloc (MBSIZE)? "Yes": "NO");
 Save = 0;
 While (Malloc (50))
  Save + = 50;
 PrintF ("Malloc (50) =% LD \ N", (long) Save);
 Return 0;
}

4, Authority 14%

The question was very good asked, and he was even lively reading. My answer is rather not the answer, but by the question of continuing the topic for some reason already accepted.

Is it possible to measure the degree of data fragmentation in the memory of your application? Alien? Maybe there is an opportunity to generally build a visual memory card with its defragmentation?

I remember during XP times there were a couple of programs that were engaged in the fact that the damp defragmented the data in RAM and sent them into the swap with long-term not use, unfortunately the example of the names of these two applications now and do not remember.

Programmers, Start Your Engines!

Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

Recent questions