Speaking once more to this topic – this time, a little more tangentally – I would make the point that the auto-garbage-collected memory models that we enjoy in interpreted languages such as (but not limited to) Perl, very convenient though they are, come at a price. There are memory-reads and memory-writes constantly being made in support of this magic. Therefore, the working-set size of any process is larger than you might expect it to be, since “merely referring-to” a datum often causes memory-writes and therefore touched-pages that you might not intuitively expect. In the OP’s case, the working set of the child blossomed to 16 megabytes. Certainly unexpected by the OP. And yet there was indeed a reason for it. Even if you were not thinking in terms of having modified anything, Perl did.
The shared-data store needs to be managed by a shared-data handling API such as one of the very-many that are available in CPAN. (I only listed the first one that came to mind.) The shared data structure should not exist in the memory-space that would be forked, but in a shared data segment or in the address-space of a single service process. (In the former case) Perl will not garbage-collect it. The plumbing and magic needed to do the trick should be concealed within the CPAN module that you select. It should not be necessary to hand-create a custom XS-based solution to this familiar requirement, in most scenarios: the work has already been well-done by others.