Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory usage for each instance #3

Open
rmolinari opened this issue Jan 31, 2023 · 4 comments
Open

Memory usage for each instance #3

rmolinari opened this issue Jan 31, 2023 · 4 comments
Labels
enhancement New feature or request

Comments

@rmolinari
Copy link

Thanks so much for this fascinating code!

I am suggesting a function that looks like this:

size_t memory_usage( <any container type> *cntr );

It would return the amount of (heap) memory associated with cntr.

Use case: when I am writing extension code for Ruby in C, the Ruby runtime likes to know how much memory is associated with a given object (although it doesn't insist on this knowledge). This helps with profiling and (I suspect) the Ruby garbage collector.

@JacksonAllan
Copy link
Owner

JacksonAllan commented Jan 31, 2023

Thanks for the suggestion!

The difficulty of trying to implement this within the library is that there is no standard, cross-platform way to determine the size of the header that malloc and friends place before the allocated block or the padding they place at the end. This problem especially affects list and the planned red-black trees, which store each node in a separate allocation (just counting the memory the library requests would result in a significant underestimate of actual memory consumption). So the issue requires some thought.

In the meantime, I can tell you that the memory usage of each container is as follows:

vecMALLOC_HDR_SIZE + sizeof( cc_vec_hdr_ty ) + cap( &our_vec ) * CC_EL_SIZE( our_vec ) + MALLOC_PADDING
listMALLOC_HDR_SIZE + sizeof( cc_list_hdr_ty ) + MALLOC_PADDING + size( &our_list ) * ( MALLOC_HDR_SIZE + sizeof( cc_listnode_hdr_ty ) + CC_EL_SIZE( our_list ) + MALLOC_PADDING )
mapMALLOC_HDR_SIZE + sizeof( cc_map_hdr_ty ) + cap( &our_map ) * CC_MAP_BUCKET_SIZE( our_map ) + MALLOC_PADDING
setMALLOC_HDR_SIZE + sizeof( cc_map_hdr_ty ) + cap( &our_set ) * CC_SET_BUCKET_SIZE( our_set ) + MALLOC_PADDING

MALLOC_HDR_SIZE is probably 8 or 16 bytes. I'm not sure what MALLOC_PADDING should be. A few minutes of experimentation with malloc_usable_size suggests that malloc on Linux rounds up the memory after the header to 24 + multiples of 16 bytes.

The memory usage of an initialized but not yet used container is effectively zero because init points the container pointer at a global, static placeholder shared among all containers of the same type. The first dynamic allocation only occurs when the first element is added.

@rmolinari
Copy link
Author

Wow! Thanks for the quick and detailed reply.

For the purposes of Ruby's runtime, a best effort seems to be enough here. So I'll use your formulas and ignore the header and padding for now. I'm sure this will be fine.

Thanks again.

@rmolinari
Copy link
Author

Q: should, say, cc_vec_hdr be cc_vec_hdr_ty ?

@JacksonAllan
Copy link
Owner

JacksonAllan commented Feb 1, 2023

Oops! Sorry. You're right — all those container header structs should be suffixed with _ty. The non-_ty identifiers are the names of internal library functions for accessing the headers. I've updated my earlier response.

@JacksonAllan JacksonAllan added the enhancement New feature or request label Feb 4, 2023
@JacksonAllan JacksonAllan changed the title Feature request: memory usage for each instance Memory usage for each instance Feb 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants