
#include "devel_template.inc" title="Bacula Memory Management"

<H1>Bacula Memory Management</H1>

<h2>General</h2>
This document describes the memory management routines
that are used in Bacula and is meant to be a
technical discussion for developers rather than
part of the user manual.
<p>Since Bacula may
be called upon to handle filenames of varying and more
or less arbitrary length, special attention needs to be
used in the code to ensure that memory buffers are 
sufficiently large. There are four possibilities for
memory usage within <b>Bacula</b>. Each will be described
in turn. They are:
<ul>
<li>Statically allocated memory.</li>
<li>Dynamically allocated memory using malloc() and free().</li>
<li>Non-pooled memory.</li>
<li>Pooled memory.</li>
</ul>
<h3>Statically Allocated Memory</h3>
Statically allocated memory is of the form:
<pre>char buffer[MAXSTRING];</pre>
The use of this kind of memory is discouraged except when you
are 100% sure that the strings to be used will be of a fixed length.
One example of where this is appropriate is for <b>Bacula</b>
resource names, which are currently limited to 127 characters
(MAX_NAME_LENGTH). Although this maximum size may change,
particularly to accommodate Unicode, it will remain a  
relatively small value.                

<h3>Dynamically Allocated Memory</h3>
Dynamically allocated memory is obtained using the standard
malloc() routines. As in:
<pre>
char *buf;
buf = malloc(256);
</pre>
This kind of memory can be released with:
<pre>
free(buf);
</pre>
It is recommended to use this kind of memory only when you
are sure that you know the memory size needed and the memory will
be used for short periods of time -- that is it would not be
appropriate to use statically allocated memory. An example might
be to obtain a large memory buffer for reading and writing files.
When <b>SmartAlloc</b> is enabled, the memory obtained by malloc()
will automatically be checked for buffer overwrite (overflow) during
the free() call, and all malloc'ed memory that is not released prior
to termination of the program will be reported as Orphaned memory.

<h3>Pooled and Non-pooled Memory</h3>
In order to facility the handling of arbitrary length filenames and
to efficiently handle a high volume of dynamic memory usage, we have
implemented routines between the C code and the malloc routines. The
first is called &quot;Pooled&quot; memory, and is memory, which
once allocated and then released, is not returned to the
system memory pool, but rather retained in a Bacula memory pool. The next
request to acquire pooled memory will return any free memory block.
In addition, each memory block has its current size associated with
the block allowing for easy checking if the buffer is of sufficient
size. This kind of memory would normally be used in high volume
situations (lots of malloc()s and free()s) where the buffer length 
may have to frequently change to adapt to varying filename lengths.
<p>The non-pooled memory is handled by routines similar to those
used for pooled
memory, allowing for easy size checking. However, non-pooled memory is
returned to the system rather than being saved in the Bacula pool. This
kind of memory would normally be used in low volume situations (few
malloc()s and free()s), but where the size of the buffer might have to
be adjusted frequently.
<h4>Types of Memory Pool</h4>
Currently there are three memory pool types:
<ul>
<li>PM_NOPOOL -- non-pooled memory.
<li>PM_FNAME -- a filename pool.
<li>PM_MESSAGE -- a message buffer pool.
<li>PM_EMSG -- error message buffer pool.</li>
</ul>
<h4>Getting Memory</h4>
To get memory, one uses:
<pre>void *get_pool_memory(pool);</pre>
where <b>pool</b> is one of the above mentioned pool names.
The size of the memory returned will be determined by the system
to be most appropriate for the application.
<p>If you wish non-pooled memory, you may alternatively call:
<pre>void *get_memory(size_t size);</pre>
The buffer length will be set to the size specified, and it will
be assigned to the PM_NOPOOL pool (no pooling).
<h4>Releasing Memory</h4>
<p>To free memory acquired by either of the above two calls, use:
<pre>void free_pool_memory(void *buffer);</pre>
where buffer is the memory buffer returned when the memory was
acquired. If the memory was originally allocated as type PM_NOPOOL,
it will be released to the system, otherwise, it will be placed
on the appropriate Bacula memory pool free chain to be used
in a subsequent call for memory from that pool.
<h4>Determining the Memory Size</h4>
To determine the memory buffer size, use:
<pre>size_t sizeof_pool_memory(void *buffer);</pre>
<h4>Resizing Pool Memory</h4>
To resize pool memory, use:
<pre>void *realloc_pool_memory(void *buffer);</pre>
The buffer will be reallocated, and the contents of the
original buffer will be preserved, but the address of the
buffer may change.
<h4>Automatic Size Adjustment</h4>
To have the system check and if necessary adjust the
size of your pooled memory buffer, use:
<pre>void *check_pool_memory_size(void *buffer, size_t new-size);</pre>
where <b>new-size</b> is the buffer length needed. Note, if the buffer
is already equal to or larger than <b>new-size</b> no buffer size change
will occur. However, if a buffer size change is needed, the original
contents of the buffer will be preserved, but the buffer address
may change. Many of the low level Bacula subroutines expect
to be passed a pool memory buffer and use this call to ensure 
the buffer they use is sufficiently large.
<h4>Releasing All Pooled Memory</h4>
In order to avoid orphaned buffer error messages when terminating
the program, use:
<pre>void close_memory_pool();</pre>
to free all unused memory retained in the Bacula memory pool.
Note, any memory not returned to the pool via free_pool_memory() will
not be released by this call.
<h4>Pooled Memory Statistics</h4>
For debugging purposes and performance tuning, the following
call will print the current memory pool statistics:
<pre>void print_memory_pool_stats();</pre>
an example output is:
<pre>
Pool  Maxsize  Maxused  Inuse
   0      256        0      0
   1      256        1      0
   2      256        1      0
</pre>

<page_prev name="Storage Media Output Format" url="mediaformat.html">
<page_next name="Bacula TCP/IP Network Protocol" url="netprotocol.html">
