Is there Zig lang type memory management in our Rust lang

1.what is zig lang manual memory management..and
2.what is the difference between rust and zig memory management system....
3.is zig type memory management present in rust or not

please ask the first question in zig forum or issue tracker.

1 Like

but what about second and third question

When you have answer about the first question.
Otherwise, how would you know if the info provided by this thread is true or not?

1 Like

can u read once

The motivation for this design philosophy is to enable users to write any manner of custom allocator strategy they find necessary, instead of forcing them or even encouraging them into a particular strategy that may not be suitable for their needs. For example, Rust seems to encourage a single global allocator strategy, which is not suitable for many usecases such as OS development and high-performance game development. Zig is taking cues from Jai's stance on allocators, since that language is being developed by a high-performance game designer for the usecase of high-performance games.

Well, yes, the standard library collections don’t have support for custom allocators, and they don’t have good support for allocation failures, either. The language itself can do it (check out the Rust compiler’s arena as well as how it’s used), but building something that works well everywhere is a lot harder than putting together some macros that work just for the one app.

2 Likes

thank for u r concern..but one small doubt..

which is not suitable for many usecases such as OS development and high-performance game development...

is it real...

because we are working on high-performance game development...

The key there is the global allocator, not the language itself. When you have specialized needs, you don't use the standard library data structures, or a global allocator. You do it yourself, or with a library that has what you need. Rust is fine for these tasks.

7 Likes

i will do it my self...any suggestions
thank u sir

I'll add that unless you're doing something that is embedded, if allocation cost is a problem the normal approach isn't so much as you change the allocator as to not allocate. All the standard collections have with_capacity constructors that often allow you to move allocation out of your inner loops.

2 Likes

If you need an arena that can allocate heterogeneous structures and you want to drop all of the memory at once, Bumpalo seems pretty neat and easy to use:

2 Likes

Good news for the (possibly distant) future:
https://www.reddit.com/r/rust/comments/jgxgpu/box_will_have_custom_allocator_support_soon_tm/g9turat/

It should be noted, that this allows replacing one global allocator with another global allocator, i.e. Rust will upgrade from a single-global-allocator language to a multi-global-allocator language.

Local allocators, on the other hand, require passing in a reference of an allocator instance. Therefore, bumpalo (and any other local allocator lib) will still have to ship with their forked stdlib types to allow their full use.

The new design does allow passing in an AllocRef, which can be either a zero-sized type for a global allocator, or a reference to a local allocator.

impl<T, A: AllocRef> Box<T, A> {
     pub fn new_in(x: T, alloc: A) -> Self { /* ... */ }
}

However, it does require the Box to store the AllocRef at run-time so that it can free its memory on drop. This takes up unnecessary space for the specific case of arena allocators like bumpalo that don't free individual allocations, which is why bumpalo still benefits from having a different box type.

It occurs to me that if we had a separate trait for deallocation and stored this in the Box instead of the AllocRef, then arena allocators could provide a no-op, zero-sized deallocator and avoid the wasted space. Something like this:

trait AllocRef {
    type Dealloc: DeallocRef;
}

struct Box<T, A: AllocRef>(T, A::Dealloc);
8 Likes

If I understand you correctly, Box::new_in would still accept AllocRef, but then retrieve DeallocRef via some method on AllocRef and only store that? That does sound like it would solve the space problem. I like it!

I hope the Allocator WG also know about this. It'd be sad, if we were stuck with stdlib type forks everywhere.

2 Likes

It's not quite that simple, because Clone requires the ability to create allocations without being passed an allocator reference.

1 Like

Good point. We could add bounds to the Clone impl like where A::Dealloc: AllocRef, which would allow cloning for "normal" allocators (where the allocator and deallocator are the same type) but not for bumpalo and its ilk. Could get a bit confusing, though.

Alternatively, we could add a Clone::clone_in method to get the AllocRef from the caller.

Would another viable alternative be to "store" the reference to the allocator in a PhantomData and implement all the AllocRef methods as no-ops?

I suppose that doesn't help with Clone, since that would start panicking at runtime if AllocRef::alloc is just hard-coded to return Err.

Box becoming larger than *T is so sad. So is the fact that for a proper API design, we now need to start writing Box<T, A> instead of just Box<T> if we want to e.g. impl a trait for boxes regardless of their allocator. When I discovered Rust, coming from C++, I was delighted to see that containers weren't parametrized on the allocator, which incurs a whole lot of mundane, repetitive mental churn on the programmer.

It would be so much better if we could keep the pointer-sized, non-parametric Box, and those who need and/or write custom allocators provided their own custom types for the niche use cases where a custom allocator is actually needed.

4 Likes