You need to hand a VM more RAM without a reboot, or pull a block out before a hot-unplug, and chmem does both. This guide uses lsmem to find the right memory block, then walks through a controlled online or offline change. It takes 10 to 15 minutes, and longer if an offline request fails and needs investigating.
Warning: this is a host-level operation. It can change the memory available to workloads, and it can fail if the kernel cannot migrate or release pages.
chmem: the package man page is from util-linux 2.39.3 and the system package reports 2.39.3-9ubuntu6.6.chmem 2.41.3 earlier in PATH. Use /usr/sbin/chmem for the Ubuntu package this guide covers.Start with a read-only inventory. The output gives you the address range, current state, block numbers, zones and the memory block size.
$ lsmem -o RANGE,SIZE,STATE,BLOCK,ZONES
RANGE SIZE STATE BLOCK ZONES
0x0000000000000000-0x0000000007ffffff 128M online 0 None
0x0000000008000000-0x00000000cfffffff 3.1G online 1-25 DMA32
0x0000000100000000-0x000000082fffffff 28.8G online 32-261 Normal
Memory block size: 128M
Total online memory: 32G
Total offline memory: 0B
Your ranges will differ, so do not copy these addresses into a production command. Pick a range or block from your own lsmem output. The requested size or address range must be aligned to the reported Linux memory block size.
Checkpoint: you have written down the exact range, block numbers, state and zone before changing anything. That record is the basis for verification and for an undo attempt.
Taking memory offline is not the same as deleting its contents. Linux first has to move or release pages, and it can refuse when pages cannot be migrated. Bringing memory online can also fail on a virtual machine when the hypervisor has none left to provide.
Warning: do not run an offline command against a guessed range, and do not test it on a busy host just to see what happens. A successful operation reduces the memory available to applications until you bring the same blocks online again.
--enable takes a size in MiB by default. Add M or G to make the unit obvious. The documented units use powers of 1024, so 2g means 2 GiB.
$ sudo /usr/sbin/chmem --enable 1024
$ sudo /usr/sbin/chmem --enable 2g
These are examples, not commands to run without checking capacity. When enabling, the program starts with the lowest memory block numbers. If the request can only be partly completed, chmem reports the amount actually changed and exits with status 64.
For a real change, replace SIZE with a size that matches the block layout you inspected:
$ sudo /usr/sbin/chmem --enable SIZE
Verify the result with the same inventory command:
$ lsmem -o RANGE,SIZE,STATE,BLOCK,ZONES
Look for the relevant block or range to show online. Also check the command status immediately after chmem:
$ printf 'chmem exit status: %s\n' "$?"
chmem exit status: 0
Use the hexadecimal range printed by lsmem to target a physical address range. The end address is the address of the last byte, not a length.
$ sudo /usr/sbin/chmem --disable 0xSTART-0xEND
Replace both placeholders with one complete, aligned range from your own output, and do not leave the literal placeholders in the command. When disabling, chmem starts with the highest memory block numbers, which matters when a size request spans several blocks.
Check the state after the command:
$ lsmem -o RANGE,SIZE,STATE,BLOCK,ZONES
$ printf 'chmem exit status: %s\n' "$?"
The exit codes:
lsmem, and do not treat a partial result as though the whole range changed.If your change is expressed in block numbers, add --blocks. It accepts a single block or an inclusive first-to-last range.
$ sudo /usr/sbin/chmem --blocks --disable BLOCK
$ sudo /usr/sbin/chmem --blocks --disable FIRST-LAST
For example, --blocks --disable 10 requests block 10, matching the form in the installed manual. Confirm the number exists in your current lsmem output first. A block number is not a byte address, so never mix it with the address-range form.
To undo a successful block-offline operation, enable the same block:
$ sudo /usr/sbin/chmem --blocks --enable BLOCK
$ lsmem -o RANGE,SIZE,STATE,BLOCK,ZONES
Recovery: undo is not guaranteed, because online and offline operations can fail for environmental reasons. If a service is degraded, restore the memory state if you can, then check its logs and the kernel log before repeating the request.
Use --zone when you need a particular valid zone and lsmem -o +ZONES shows the range supports it. When bringing memory online, chmem prefers the Movable zone when available. Movable memory is easier to offline again, but it is restricted to migratable pages rather than arbitrary kernel allocations.
$ lsmem -o RANGE,SIZE,STATE,BLOCK,+ZONES
$ sudo /usr/sbin/chmem --enable --zone Movable SIZE
Do not assume every machine offers every zone. The installed command advertises DMA, DMA32, Normal, Highmem, Movable and Device, but the valid choices for a particular range come from that machine's lsmem output. A zone option selects placement. It does not create a zone or override the kernel's suitability checks.
2g when you mean 2 GiB.command -v chmem may find another util-linux build first. Check chmem --version, or call /usr/sbin/chmem for the Ubuntu package.$? immediately. Running lsmem first replaces chmem's exit status.lsmem.