Memory allocations are linked with operations on tensors, layers just wrap groups of these operations together. So, it is kinda hard to measure memory, as layer code may create intermediate tensors, some will be freed early, some kept for backpropagation. Check pytorch_memlab 3 if you need a detailed profile.
ReLU allocates new memory for output by default, and it is usually not released, as next layer (linear/conv) keeps it for gradient calculations.