Shrink VirtualBox VDI Hard Disks
I run VirtualBox on a Linux host with a variety of different operating systems as guests. I almost always use dynamic disks and after awhile they grow significantly even though the guest may not be using the entire disk. If you search around you'll get a variety of recommendations on how to shrink them, some of which absolutely do not work. For example, recommendations to use sdelete on Windows guests (with either the -z or -c option) did not work for me.
Here's what does work without fail.
To get started, fire up the VM.
If it's a Windows VM, first clean and defragment the hard drive. Then, download dd for Windows (if you don't already have it under Cygwin or MinGW/MSYS) from http://www.chrysocome.net/dd. Open a cmd.exe window and run:
dd if=/dev/zero of=EMPTY bs=1M
When it finishes due to no more space, then run:
If you have a Linux or related VM, do something similar:
dd if=/dev/zero of=EMPTY bs=1M; rm -f EMPTY
If you have a swap partition, and you likely do, you can also zero that out with a little more care. First, figure out where you swap partition is.
Then, turn swap off and zero the partition. After that, you'll need to re-format the swap partition. Be warned, that you'll probably need to update /etc/fstab if it was using a UUID to identify the partion.
sudo swapoff -a sudo dd if=/dev/zero of=/dev/sdaX bs=1M sudo mkswap /dev/sdaX
After you've written zeros to all of the free space from within the VM, shutdown and get ready to compact. Go to the directory containing the VDI and run:
vboxmanage modifyhd disk.vdi --compact
You'll notice the hard disk is now actually taking up almost the same exact amount of space the guest is actually using. VirtualBox can optimize how it saves large chunks of "zeros" so that it doesn't need to actually take up any disk space at all on the host.