\input{configpres} \title{Linux Memory Management} \maketitle \subsection{Linux Memory Management} \begin{frame} \frametitle{Overview} \tableofcontents \end{frame} \subsubsection{Basics} \begin{frame} \frametitle{Overview} \begin{itemize} \item over-committing \item Copy-On-Write \item Page relocation \end{itemize} \end{frame} \begin{frame} \frametitle{over-committing} \begin{itemize} \item Comparable to those low-cost airlines ;) \pause \item ...selling more tickets than available seats \pause \item ...hoping not everyone will come ;) \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{over-commit settings} \begin{verbatim} /proc/sys/vm/overcommit_memory \end{verbatim} Possible settings are: \begin{itemize} \item 0: Heuristic overcommit handling (default) \item 1: Always overcommit \item 2: Don't overcommit \end{itemize} \end{frame} \begin{frame} \frametitle{The OOM Killer} ...is invoked if you ask for more memory than available.\\ \pause \textbf{Result}: The kernel kills a task \end{frame} \begin{frame} \frametitle{Copy-On-Write} \begin{itemize} \item completely transparently for userspace \item you don't need the same data twice \item only updated if one virtual memory area is updated \end{itemize} \end{frame} \begin{frame} \frametitle{Page relocation} \begin{itemize} \item AKA paging or swapping \item Linux can move a page to / from swap \item also completely transparently for userspace \end{itemize} \end{frame} \subsubsection{The stack} \begin{frame} \frametitle{The stack} \begin{itemize} \item Grows top - down \item Configurable stack size \item Stack grows on demand. Access beyond current size ends up in a ''Stackfault'' which is handled by the kernel \item ulimit -a shows the current maximum stack size \item ulimit -s \emph{size} sets the maximum stack size \item Default maximum stack size is 8MiB \end{itemize} \end{frame} \subsubsection{The heap} \begin{frame} \frametitle{The heap: Userland handling} \begin{itemize} \item Memory is allocated using malloc() \item Memory is freed using free() \item malloc() uses the mmap() and the sbrk() system calls \end{itemize} \end{frame} \begin{frame} \frametitle{The heap: Userland handling} \begin{itemize} \item For small chunks, malloc() allocates memory from the heap and adjusts the size using sbrk() \item For larger blocks (larger than defined in MMAP\_THRESHOLD) the memory is allocated as private, anonymous mapping \item MMAP\_THRESHOLD is 128kb by default \end{itemize} \end{frame} \begin{frame} \frametitle{malloc()} \begin{itemize} \item Keep over-commit in mind! \item If over-commit is enabled: A non-null return value from malloc() doesn't guarantee that the memory really is available. \end{itemize} \end{frame} \subsection{Do's and Dont's} \subsubsection{The heap} % fragmentation % check return value % ulimit (limit memory consumption) \begin{frame} \frametitle{Return value} Always check malloc's return value!! \end{frame} \begin{frame} \frametitle{How to avoid heap fragmentation} \begin{itemize} \item GLIBCs malloc() itself tries to avoid fragmentation \item The allocator can't avoid fragmentation caused by a bad application design! \item Try to re-use memory pools \item free memory you don't need anymore! \end{itemize} \end{frame} \begin{frame} \frametitle{How to limit memory consumption} ulimit: \begin{itemize} \item ulimit -s sets the maximum stack size \item ulimit -d sets a limit for the data segment \item ulimit -v sets a limit for the virtual memory \item Check limits with ulimit -a \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{ulimit example} \scriptsize \begin{verbatim} $ ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 20 file size (blocks, -f) unlimited pending signals (-i) 16382 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) unlimited virtual memory (kbytes, -v) unlimited file locks (-x) unlimited \end{verbatim} \end{frame} \subsection{Realtime} \subsubsection{General} \begin{frame}[fragile] \frametitle{Locking the memory} \begin{verbatim} /* Lock memory */ if(mlockall(MCL_CURRENT|MCL_FUTURE) == -1) { perror("mlockall failed"); exit(-2); } \end{verbatim} \end{frame} \subsubsection{Stack} \begin{frame}[fragile] \frametitle{Stack prefaulting} \begin{verbatim} #define MAX_SAFE_STACK (8*1024) void stack_prefault(void) { unsigned char dummy[MAX_SAFE_STACK]; memset(&dummy, 0, MAX_SAFE_STACK); return; } \end{verbatim} \end{frame} \subsubsection{Heap} \begin{frame} \frametitle{Allocations from Realtime context} \begin{itemize} \item If possible, avoid memory allocations from Realtime context \item Try to use a pre-allocated buffer \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{Disable malloc trimming and mmap usage} \begin{verbatim} mallopt(M_TRIM_THRESHOLD, -1); mallopt(M_MMAP_MAX, 0); \end{verbatim} \end{frame} \begin{frame}[fragile] \frametitle{Reserve process memory} \begin{verbatim} static void reserve_process_memory(int size) { int i; char *buffer; buffer = malloc(size); /* Touch each page in this piece of * memory to get it mapped into RAM */ for (i = 0; i < size; i += sysconf(_SC_PAGESIZE)) buffer[i] = 0; free(buffer); } \end{verbatim} \end{frame} \subsection*{sources} \begin{frame} \frametitle{sources} \begin{thebibliography}{1} \bibitem{mmm} http://cftw.wordpress.com/2009/11/02/introduction-to-the-linux-memory-management/ \bibitem{mmm} http://rt.wiki.kernel.org/ \end{thebibliography} \end{frame} \input{tailpres}