Do be aware that Devel::Size
does count shared data in part of its size calculation when figuring out how big what you're checking is, but it only counts it once per call, so if the two hashes share some data, and they might, pass them in together for a correct aggregate total. Something like:
print total_size([\%hash1, \%hash2]);
though that'll add in a few dozen bytes for the two refs and the anon array.
Also, don't rule out the possibility that there's a lot of scrap memory hanging around that Perl's not cleaned up after quite yet, or that you've not noticed.