Python
import gc
import sys

def get_obj_size(obj):
    marked = {id(obj)}
    obj_q = [obj]
    sz = 0

    while obj_q:
        sz += sum(map(sys.getsizeof, obj_q))

        # Lookup all the object referred to by the object in obj_q.
        # See: https://docs.python.org/3.7/library/gc.html#gc.get_referents
        all_refr = ((id(o), o) for o in gc.get_referents(*obj_q))

        # Filter object that are already marked.
        # Using dict notation will prevent repeated objects.
        new_refr = {o_id: o for o_id, o in all_refr if o_id not in marked and not isinstance(o, type)}

        # The new obj_q will be the ones that were not marked,
        # and we will update marked with their ids so we will
        # not traverse them again.
        obj_q = new_refr.values()
        marked.update(new_refr.keys())

    return sz
    
import random
my_dict = {}
my_list = []
TSZ = 1000000
SZ = 10000
key = 0
# Generate SZ random int32 keys and values
for i in range(SZ):
    key += random.randint(0, (TSZ/SZ)-1)
    value = random.randint(-2147483648, 2147483647)
    my_dict[key] = value
    my_list.append(key)
    my_list.append(value)
print(SZ, " values dict size: ", get_obj_size(my_dict))
print(SZ, " values list size: ", get_obj_size(my_list))

import numpy as np
my_array = np.array(my_list).astype(np.int32)
print(SZ, " values array size: ", get_obj_size(my_array))