- How do I allocate heap memory in Linux?
- How do I change Java heap memory in Linux?
- What is Java heap memory?
- Is memory allocated on stack or on heap?
- What are the differences between heap and stack memory?
- Linux heap allocation
- Sysadminium
- Общая информация
- Виртуальная и резидентная память
- Раздел или файл подкачки
- Память процессов
- Страничный кеш
- HugePages
- Итог
How do I allocate heap memory in Linux?
We allocate memory from the heap using the malloc() function. The argument we want to include in malloc is the amount of memory we want to allocate to our application, in bytes.
How do I change Java heap memory in Linux?
- Log in to the Application Server Administration Server.
- Navigate to the JVM options.
- Edit the -Xmx256m option.
- This option sets the JVM heap size.
- Set the -Xmx256m option to a higher value, such as Xmx1024m.
- Save the new setting.
How do I check my Java heap size?
You can verify that the JVM is using the increased Java heap space: Open a terminal window. Review the command output. The argument beginning with “-Xmx” will give you the value of the current Java heap space.
What is heap memory in Linux?
The heap is where all user-allocated memory is located. The heap grows up from a lower memory address to a higher memory address. Stack—whenever a program makes a function call, the current function’s state needs to be saved onto the stack.
What is Java heap memory?
The Java heap is the area of memory used to store objects instantiated by applications running on the JVM. Objects in the heap can be shared between threads. Many users restrict the Java heap size to 2-8 GB in order to minimize garbage collection pauses.
Is memory allocated on stack or on heap?
The stack (sometimes called the runtime stack) contains all of the automatic (i.e., non-static) variables. Memory is allocated from and returned to the heap with with the new and delete operators respectively. It’s easy to get confused by the term “allocate” when we talk about a C++ program in the context of hardware and the operating system.
How is heap memory allocated to a process?
Heap Allocation: The memory is allocated during the execution of instructions written by programmers . Note that the name heap has nothing to do with the heap data structure. It is called heap because it is a pile of memory space available to programmers to allocated and de-allocate.
Why does Java use heap for memory allocation?
Java Heap space is used by java runtime to allocate memory to Objects and JRE classes . Whenever we create an object, it’s always created in the Heap space. Garbage Collection runs on the heap memory to free the memory used by objects that don’t have any reference.
What are the differences between heap and stack memory?
Stack and Heap are the two ways memory is allocated in the operating system. Stack segment is used to store local function variables that are created automatically, whereas heap segment is used for dynamically allocated memory.
Linux heap allocation
In FreeRTOS , the heap is simply a global array with a size (lets call is heapSize ) defined in a H file which the user can change. This array is a non-initialized global array which makes it as part of the BSS section of the image, as so it is filled with zeros upon loading, then, every allocation of memory is taken from this array and every address of allocated memory is a an offset of this array. So, for a maximal utilization of the memory size, we can approximate the size of the Data , Text and BSS areas of our entire program, and define the heap size to something like heapSize = RAM_size — Text_size — Data_size — BSS_size . I would like to know what is the equivalent implementation is Linux OS. Can Linux scan a given RAM and decide its size in run time? does linux have an equivalent data structure to manage the heap? if so, how does it allocates the memory for this data structure in the first place?
Linux’ memory management is far to complex to be sufficiently described in the StackOverflow Q&A format. Most importantly Linux is a virtual memory OS, that separated address space in kernel and user land, with different memory allocation method for each.
Linux allows allocation at page granularity (which is used for process memory and some large in-system memory areas) and structure/buffer granularity which uses one of the available allocators: SLAB/SLUB (which is actually not heap but a list of lists of blocks of the same size) and SLOB (much simpler, targeted or embedded).
Sysadminium
В этой статье будет рассмотрена общая информация о том, как в Linux используется оперативная память. Разберём основные моменты и термины.
Общая информация
Вся оперативная память в системе Linux делится на страницы. Страница — это минимальная единица памяти, с которой происходит работа. По размеру страницы разделяются на:
Помимо страниц память делится на зоны:
- DMA — эта зона занимает 16MB;
- DMA32 — эта зона занимает 4 GB и существует только на 64-разрядных системах;
- Normal — вся остальная память.
Зоны DMA и DMA32 содержат страницы, которые совместимы с режимом DMA. Режим DMA (direct memory access) — это прямой доступ к памяти со стороны периферийного устройства без участия процессора. Если оборудование работает с памятью в режиме DMA, то оно занимает память из этой зоны и не может брать страницы из зоны Normal.
В оперативной памяти хранятся:
- данные ядра;
- данные процессов;
- файлы, которые были прочитаны с жесткого диска или записаны на него.
За выделение оперативной памяти отвечает ядро Linux.
Виртуальная и резидентная память
Выделяемая память процессу может быть либо резидентная, либо виртуальная. В листинге ниже видно у процессов резидентную (rss) и виртуальную память (vsz). Эта память отображается в KB.
$ ps -C apache2 -o pid,user,rss,vsz,comm PID USER RSS VSZ COMMAND 403 root 7316 11188 apache2 405 www-data 7032 1216200 apache2 406 www-data 11128 1216200 apache2
Виртуальная память (VSZ) — это память которую выделили процессу, но не факт что он успел в эту память что-то записать.
Резидентная память (RSS) — это память которую процесс занял, то есть что-то сохранил в виртуальную память. Именно резидентная память показывает сколько процесс потребляет физической памяти.
Приложение может запросить много памяти, а использовать малую её часть. Поэтому почти всегда rss меньше чем vsz.
Раздел или файл подкачки
Раздел подкачки (SWAP) — это раздел на жестком диске, куда помещаются:
- редко используемые данные из резидентной памяти;
- любые данные при нехватки физической памяти.
Если какие-то данные из rss сбрасываются в swap то rss освобождается, а vsz нет. От сюда следует что данные процесса, которые лежат в swap, входят в виртуальную память этого процесса.
Linux умеет работать не только с разделом подкачки, но и с файлом подкачки. То есть данные из резидентной памяти могут сбрасываться в специальный файл, который лежит на жёстком диске.
И файл и раздел подкачки имеет тот же самый формат что и оперативная память. То есть данные в оперативной памяти хранятся в виде страниц, и в подкачку сбрасываются в виде таких же страниц.
Память процессов
Посмотреть более подробно на используемую память процесса поможет файл /proc//status. Из предыдущего листинга видно что процесс с номером pid=406 занимает 11128 KB памяти.
$ grep Rss /proc/406/status RssAnon: 8328 kB RssFile: 2736 kB RssShmem: 64 kB
- RssAnon — rss не сопоставляемая с каким-нибудь файлом на диске;
- RssFile — rss сопоставляемая с каким-нибудь файлом на диске;
- RssShmem — rss разделяемая память, которая может использоваться другими процессами (Shared Memory);
В этом же файле можно посмотреть на виртуальную память:
$ grep Vm /proc/406/status VmPeak: 1281736 kB VmSize: 1216200 kB VmLck: 0 kB VmPin: 0 kB VmHWM: 11128 kB VmRSS: 11128 kB VmData: 225044 kB VmStk: 132 kB VmExe: 316 kB VmLib: 5024 kB VmPTE: 240 kB VmSwap: 0 kB
- VmPeak — пиковый размер использования виртуально памяти;
- VmSize — размер виртуальной памяти в данный момент;
- VmHWM — пиковый размер использования резидентной памяти;
- VmRSS — размер резидентной памяти в данный момент;
- VmExe — код приложения;
- VmLib — используемые библиотеки;
- VmSwap — часть данных сброшенная на раздел подкачки.
Когда память выделяется процессу то обычно выделяется не одна страница памяти, а какой-то блок. Такой блок страниц памяти называется virtual memory area (VMA). Такой группе сразу назначаются права:
- r — можно читать данные из памяти;
- w — можно записывать данные в памяти;
- e — можно выполнять исполняемые файлы.
Также группе назначаются и друге параметры, например:
- p — приватная память для данного процесса;
- s — общая память (shared memory).
Страничный кеш
Больше всего в системе память занимает страничный кеш (Page Cache). Вся работа с файлами на диске (запись или чтение) идет через Page Cache. Запись в linux всегда быстрее чтения, так как запись вначале идет в Page Cache, а затем сбрасывается на диск. А при чтении ядро ищет файл в Page Cache, и если не находит читает файл с диска. Узнать сколько сейчас система тратит памяти на Page Cache можно выполнив команду free:
$ free -h total used free shared buff/cache available Mem: 976Mi 74Mi 764Mi 0,0Ki 137Mi 765Mi Swap: 974Mi 0B 974Mi
Страничный кеш показан в колонке buff/cache. Как мы видим у нас занято 137MB страничным кешем. Хотя тут не только Page Cache, тут также находится Buffer, который тоже связан с файлами на диске.
Посмотреть информацию по Page Cache и Buffer отдельно можно в файле /proc/meminfo:
$ egrep "^Cach|^Buff" /proc/meminfo Buffers: 16012 kB Cached: 101220 kB
При создании нового файла, запись идет в cache, а страницы памяти для этого файла помечаются как грязные (dirty). Раз в какой-то промежуток времени грязные страницы сбрасываются на диск, и если таких страниц будет слишком много, то они тоже сбросятся на диск. Управлять этим можно через параметры sysctl ( $ sudo nano /etc/sysctl.conf ):
- vm.dirty_expire_centisecs — интервал сброса грязных страниц на диск в сотых долях секунд (100 = 1с);
- vm.dirty_ratio — объем оперативной памяти в процентах который может быть выделен под Page Cache.
$ sudo sysctl vm.dirty_expire_centisecs vm.dirty_expire_centisecs = 3000 $ sudo sysctl vm.dirty_ratio vm.dirty_ratio = 20
Существует утилита — vmtouch, она может показать какой процент указанного файла находится в страничном кеше. Но её нужно скачивать из git и устанавливать:
$ sudo apt update $ sudo apt install git make gcc $ git clone https://github.com/hoytech/vmtouch.git $ cd vmtouch $ make $ sudo make install $ vmtouch /etc/passwd Files: 1 Directories: 0 Resident Pages: 1/1 4K/4K 100% Elapsed: 6.3e-05 seconds
Видно что весь файл /etc/passwd сейчас находится в Page Cache (Resident Pages).
Узнать объем грязных страниц можно из файла /proc/meminfo. А команда sync записывает грязные страницы на диск:
$ grep Dirty /proc/meminfo Dirty: 24 kB # sync $ grep Dirty /proc/meminfo Dirty: 0 kB
HugePages
Поговорим немного про большие страницы HugePages. Особенности таких страниц:
- размер таких страниц равен 2MB;
- приложение должно уметь работать с такими страницами;
- эти страницы никогда не сбрасываются в swap.
Выделить под HugePages страницы можно параметром sysctl:
- vm.nr_hugepages = (так если указать 1024 то выделится 1024*2МБ=2048MB).
- vm.hugetlb_shm_group = — только члены этой группы могут использовать HugePages.
После исправления /etc/sysctl.conf нужно перезагрузиться и посмотреть на результат в файле /proc/meminfo:
$ egrep "HugePages_T|HugePages_F" /proc/meminfo HugePages_Total: 1024 HugePages_Free: 1024
Выделено 1024 страниц и все они свободны. При этом у нас 2GB памяти не сможет использоваться обычными приложениями, которые не умеют работать с HugePages. Поэтому не всегда нужно выделять HugePages.
Итог
Вот мы и узнали как в Linux используется оперативная память. Оперативная память разбивается на страницы по 4KB, а при определенных настройках можно выделить большие страницы (2MB), которые называются HugePages. Ещё оперативная память в Linux разбивается на зоны: DMA, DMA32, Normal.
В оперативной памяти хранятся данные пользовательских процессов, данные ядра и файлы которые дублируются с диска.
Память которая выделяется процессам может быть виртуальная (vsz) или резидентная (rss). При этом память выделяется блоками страниц, которые называются virtual memory area (VMA). И этому блоку назначаются определенные атрибуты.
Есть раздел подкачки, куда сбрасывается резидентная память при необходимости.
Работа с файлами на диске также идет через оперативную память, для этого выделяется Cache и Buffer. Страницы которые изменились в памяти но не изменились на диске помечаются грязными (Dirty). Грязные страницы записываются на диск по расписанию или утилитой sync.
Файлы для исследование памяти:
Утилиты для исследования памяти:
Настраивать работу с памятью можно через параметры sysctl (/etc/sysctl.conf):
- vm.dirty_expire_centisecs — интервал сброса грязных страниц;
- vm.dirty_ratio — объем оперативной памяти в процентах который может быть выделен под Page Cache;
- vm.nr_hugepages — число больших страниц, которые нужно выделить;
- vm.hugetlb_shm_group — группа, члены которой могут работать с большими страницами.