Internal fragmentation is a memory issue that occurs when the allocator leaves extra space empty inside an allocated memory block. For example, let's say an allocator can only provide memory in chunks of 4 bytes. If a program requests 29 bytes of memory, it will actually receive a chunk of 32 bytes. Since the program uses only 29 of the 32 available bytes, the excess 3 bytes of memory goes to waste.
Over time, tiny chunks of unused memory build up and create large amounts of memory the allocator cannot put to use. The two most effective ways to prevent internal fragmentation are to allocate memory dynamically or to use partitions of different sizes.