If you work with dynamically sized disk images in VirtualBox, you will notice that the image size increases over time as you’re working with the VM, but also that the size will not decrease if you delete files inside it. This has two reasons:
- Just like on physical disks, when you delete a file, it is not actually deleted. The operating system just “removes it from the index” and marks the corresponding blocks as free.
- Every disk block that contained data before will remain in the virtual disk image even if the block is now empty (zeros). So if you securely delete a file or fill the free space with zeros, the image size will not automatically decrease.
But VirtualBox has features to manually reduce the image size. These however require prior zeroing of the free space inside the VM with a third-party tool. Additionally, these are only effective if the VM does not have any snapshots, which means that you’ll have to delete all snapshots or clone a new VM from the desired state. Then there are two approaches to reduce the image size
- Using the command-line utility VBoxManage you can execute a command to remove free space (zeros) from the disk image. This only works with VDI files at this time.
- Alternatively you can clone the VM again after zeroing the free space. Doing so, only the blocks that actually contain data will be copied into the new machine/image.
Caution: If the VM has snapshots, zeroing the free space leads to the current differential image getting very large (–> as large as the virtual disk size).
Both approaches explained in detail:
1. Merge All Snapshots or Clone
Restore the machine’s state that you want to keep and then delete all snapshots, so that you end up with just the base VDI containing your current state. Caution: Deleting snapshots is a critical process that might break the VM if something goes wrong, so I recommend to have a recent backup, just in case. Alternatively you can clone the desired state into a new machine.
2. Fill Free Space With Zeros
Now boot up your VM and fill the free space with zeros.
Get the sdelete utility from Sysinternals and run it as follows:
You can use a utility like zerofree but you can also do it with dd:
sudo dd if=/dev/zero of=/emptyfile bs=1M
sudo rm -rf /emptyfile
This will create one big file that only contains zeros. The file will get as big as the free space was before, so dd will abort when there is no free space left. Then you just delete the file.
3. Compact The VDI
VBoxManage modifyhd somedisk.vdi --compact
1. Prepare The Machine
See A.1 and A.2
2. Clone The Machine
Use the Virtual Box GUI to clone the current state into a new VM or use the following VBoxManage command:
This will clone the current state into a new machine and add it to VirtualBox. You could also use the clonehd command, but then you would have to deal with filenames and UUIDs.