\section{Memory Monitoring and Tuning}
\begin{frame}
   {Memory Monitoring}

   Important tools for monitoring and tuning memory in \textbf{Linux}

   \begin{table}[H]
      \caption{Memory Monitoring Utilities}
      \vspace{-15pt}
   \end{table}

   \small{\begin{tcolorbox}[tabularx={p{0.25\textwidth}|X|p{0.25\textwidth}}]

         \textbf{Utility}
         &
         \textbf{Purpose}
         &
         \textbf{Package}
         \\ \hline
         \textbf{free}
         &
         Brief summary of memory usage
         &
         procps
         \\ \hline
         \textbf{vmstat}
         &
         Detailed virtual memory statistics and block I/O,
         dynamically updated
         &
         procps
         \\ \hline
         \textbf{pmap}
         &
         Process memory map
         &
         procps
      \end{tcolorbox}}

   \begin{cmd}
$ free -m
   \end{cmd}
   \begin{response}
           total     used     free      shared  buff/cache   available
Mem:       15901     2080     9317         992        4502       12457
Swap:       8095        0     8095
   \end{response}


\end{frame}

\cprotect\note{

   Over time, systems have become more demanding of
   memory resources at the same time RAM prices have
   decreased and performance has improved.

   Yet, it is often the case that bottlenecks in
   overall system performance and throughput are
   memory-related; the CPUs and the I/O subsystem can
   be waiting for data to be retrieved from or written
   to memory.

   There are many tools for monitoring, debugging and tuning
   a system's behavior with regard to its memory.

   Tuning the memory sub-system can be a complex
   process. First of all, one has to take note that memory
   usage and I/O throughput are intrinsically related, as, in
   most cases, most memory is being used to cache the
   contents of files on disk.

   Thus, changing memory parameters can have a large effect
   on I/O performance, and changing I/O parameters can have
   an equally large converse effect on the virtual memory
   sub-system.

}
\clearpage
\begin{frame}
   {/proc/meminfo}

   \begin{cmd}
$ cat /proc/meminfo
   \end{cmd}

   \begin{multicols}{3}
      %% \respfile{meminfo.output}
      \begin{responsett}     
MemTotal:       16265960 kB
MemFree:        10481080 kB
MemAvailable:   12596456 kB
Buffers:          177824 kB
Cached:          2768600 kB
SwapCached:            0 kB
Active:          3320564 kB
Inactive:        1566504 kB
Active(anon):    2381096 kB
Inactive(anon):   218792 kB
Active(file):     939468 kB
Inactive(file):  1347712 kB
Unevictable:      437372 kB
Mlocked:              32 kB
SwapTotal:      21580796 kB
SwapFree:       21580796 kB
Dirty:               288 kB
Writeback:             0 kB
AnonPages:       2248272 kB
Mapped:           811700 kB
Shmem:            659452 kB
KReclaimable:     159792 kB
Slab:             307548 kB
SReclaimable:     159792 kB
SUnreclaim:       147756 kB
KernelStack:       15680 kB
PageTables:        74940 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:    29713776 kB
Committed_AS:   10239968 kB
VmallocTotal:   34359738367 kB
VmallocUsed:       24592 kB
VmallocChunk:          0 kB
Percpu:             6688 kB
HardwareCorrupted:     0 kB
AnonHugePages:    716800 kB
ShmemHugePages:        0 kB
ShmemPmdMapped:        0 kB
FileHugePages:         0 kB
FilePmdMapped:         0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
Hugetlb:               0 kB
DirectMap4k:      258124 kB
DirectMap2M:     9052160 kB
DirectMap1G:     8388608 kB
\end{responsett}
   \end{multicols}
\end{frame}

\cprotect\note{

   The pseudofile \filelink{/proc/meminfo} contains a wealth of
   information about how memory is being used.

}
\section{/proc/sys/vm}

\begin{frame}
   {/proc/sys/vm}

   \begin{itemize}

      \item
      Contains many tunable knobs to
      control the Virtual Memory system
      \item
      Almost all of the entries are writable (by root)

      \item
      Exactly what appears in
      this directory will depend somewhat on the kernel
      version.

      \item
      Values can be changed either by directly
      writing to the entry, or using \textbf{sysctl}

   \end{itemize}

\end{frame}

\cprotect\note{

   When tweaking parameters in \filelink{/proc/sys/vm}, the
   usual best practice is to adjust one thing at a time and
   look for effects. The primary (inter-related) tasks are:

   \begin{itemize}
      \item
      Controlling flushing parameters; i.e., how many pages
      are allowed to be dirty and how often they are flushed
      out to disk.
      \item
      Controlling swap behavior; i.e., how much pages that
      reflect file contents are allowed to remain in memory,
      as opposed to those that need to be swapped out as they
      have no other backing store.
      \item
      Controlling how much memory overcommission is allowed,
      since many programs never need the full amount of memory
      they request, particularly because of copy on write
      (COW) techniques.
   \end{itemize}
   Memory tuning can be subtle: what works in one
   system situation or load may be far from optimal in other
   circumstances.

   \begin{figure}[H]
      \includegraphics[width=5.25in]{IMAGES/procsysvm}
      \caption{/proc/sys/vm}
   \end{figure}

}
\section{vmstat}
\begin{frame}
   {vmstat}

   \begin{itemize}

      \item
      Displays information about memory, paging, I/O, processor
      activity and processes.

      \item
      Many options
      \begin{cmd}
$ vmstat [options] [delay] [count]
      \end{cmd}

      \item
      \verb?delay? is given in seconds, report is repeated \verb?count? times.

      \item
      First line shows averages since the last
      reboot
      \item
      Succeeding lines show activity during the
      specified interval.
   \end{itemize}

   \begin{figure}[H]
      \includegraphics[width=6in]{IMAGES/vmstat}
      \caption{vmstat}
   \end{figure}

\end{frame}

\cprotect\note{

   If the option \verb?-S m? is given, memory statistics will
   be in MB instead of KB.

   With the \verb?-a? option, \textbf{vmstat} displays information about active
   and inactive memory pages: active  pages are those
   recently used; they may be clean (disk
   contents are up to date) or dirty (need to be flushed to
   disk eventually). By contrast, inactive memory pages have
   not been recently used and are more likely to be clean and
   are released sooner under memory pressure:

   Memory moves back and forth between active and inactive
   lists, with new references, or a long time
   between uses.

   \begin{figure}[H]
      \includegraphics[width=4.75in]{IMAGES/vmstata}
      \caption{Using vmstat}
   \end{figure}
   \vspace{-24pt}
   If you just want to get some quick statistics on only one
   partition, use the \verb?-p? option
   \begin{figure}[H]
      \includegraphics[width=4.75in]{IMAGES/vmstatp}
      \caption{Using vmstat on One Disk}
   \end{figure}
}

\section{Out of Memory Killer (OOM)}

\begin{frame}
   {OOM Killer}

   \begin{itemize}
      \item
      Systems may run out of physical memory.  One can:
      \begin{enumerate}
         \item Deny any further memory requests until memory is freed up
         \item Extend physical memory by the use of \textbf{swap} space
         \item Terminate (intelligently) selected processes to reduce memory usage
         and let the system survive
      \end{enumerate}
      \item \textbf{Linux} systems most often implement the second and third
      methods
      \item Which processes are terminated is selected by the
      \textbf{OOM} killer
   \end{itemize}
\end{frame}

\cprotect\note{

   The simplest way to deal with memory pressure would be to
   permit memory allocations to succeed as long as free memory
   is available and then fail when all memory is exhausted.

   The second simplest way is to use swap space on disk to push
   some of the resident memory out of core; in this case, the
   total available memory (at least in theory) is the actual
   RAM plus the size of the swap space. The hard part of this
   is to figure out which pages of memory to swap out when
   pressure demands. In this approach, once the swap space
   itself is filled, requests for new memory must fail.

   Linux, however, goes one better; it permits the system to
   overcommit memory, so that it can grant memory requests that
   exceed the size of RAM plus swap. While this might seem
   foolhardy, many (if not most) processes do not use all
   requested memory.

   An example would be a program that allocates a 1 MB buffer,
   and then uses only a few pages of the memory. Another
   example is that every time a child process is forked, it
   receives a copy of the entire memory space of the
   parent. Because Linux uses the COW (copy on write)
   technique, unless one of the processes modifies memory, no
   actual copy needs be made. However, the kernel has to assume
   that the copy might need to be done.

   Thus, the kernel permits overcommission of memory, but only
   for pages dedicated to user processes; pages used within the
   kernel are not swappable and are always allocated at request
   time.


}

\begin{frame}
   {OOM Killer Algorithms}

   \begin{itemize}

      \item
      Heuristic algorithm is not intended to be depended on for
      normal operations.  Is there more for a graceful shutdown or
      retrenchment
      \item
      Process selection depends on a \textbf{badness} value which can
      be read from \filelink{/proc/[pid]/oom_score} for each process
      \item
      Adjustments can be made to a process's \file{oom\_adj\_score} in the
      same directory for each task.
   \end{itemize}

\end{frame}

\cprotect\note{

   One can modify, and even turn off overcommission by
   setting the value of
   \filelink{/proc/sys/vm/overcommit_memory}:
   \begin{itemize}

      \item 0: (default) Permit overcommission, but refuse
      obvious overcommits, and give root users somewhat more
      memory allocation than normal users.

      \item 1: All memory requests are allowed to overcommit.

      \item 2: Turn off overcommission. Memory requests will fail
      when the total memory commit reaches the size of the
      swap space plus a configurable percentage (50 by
      default) of RAM. This factor is modified changing
      \filelink{/proc/sys/vm/overcommit_ratio}.

   \end{itemize}
   An amusing take on this was given by Andries Brouwer
   (\url{https://lwn.net/Articles/104185/}):

   \begin{quote}\small{

         An aircraft company discovered that it was cheaper to
         fly its planes with less fuel on board. The planes
         would be lighter and use less fuel and money was saved.
         On rare occasions however the amount of fuel was
         insufficient, and the plane would crash. This problem
         was solved by the engineers of the company by the
         development of a special OOF (out-of-fuel) mechanism.
         In emergency cases a passenger was selected and thrown
         out of the plane. (When necessary, the procedure was
         repeated.) A large body of theory was developed and
         many publications were devoted to the problem of
         properly selecting the victim to be ejected. Should the
         victim be chosen at random? Or should one choose the
         heaviest person? Or the oldest? Should passengers pay
         in order not to be ejected, so that the victim would be
         the poorest on board? And if for example the heaviest
         person was chosen, should there be a special exception
         in case that was the pilot? Should first class
         passengers be exempted? Now that the OOF mechanism
         existed, it would be activated every now and then, and
         eject passengers even when there was no fuel shortage.
         The engineers are still studying precisely how this
         malfunction is caused.
      }
   \end{quote}



}







