<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # 自定義內存分配器 > [custom-allocators.md](https://github.com/rust-lang/rust/blob/master/src/doc/book/custom-allocators.md) commit 6ba952020fbc91bad64be1ea0650bfba52e6aab4 分配內存并不總是最簡單的事情,同時通常 Rust 默認會負責它,不過經常自定義內存分配會變得必要。編譯器和標準庫目前允許在編譯時切換目前默認使用的全局分配器。設計目前稱作[RFC 1183](https://github.com/rust-lang/rfcs/blob/master/text/1183-swap-out-jemalloc.md)不過這里我們會教你如何獲取你自己的分配器并運行起來。 ### 默認分配器 編譯器目前自帶兩個默認分配器:`alloc_system`和`alloc_jemalloc`(然而一些目標平臺并沒有 jemalloc)。這些分配器是正常的 Rust crate 并包含分配和釋放內存的 routine 的實現。標準庫并不假設使用任何一個編譯,而且編譯器會在編譯時根據被產生的輸出類型決定使用哪個分配器。 編譯器產生的二進制文件默認會使用`alloc_jemalloc`(如果可用的話)。在這種情況下編譯器“控制了一切”,從它超過了最終鏈接的權利的角度來看。大體上這意味著分配器選擇可以被交給編譯器。 動態和靜態庫,然而,默認使用`alloc_system`。這里 Rust 通常是其他程序的“客人”或者處于并沒有權決定應使用的分配器的世界。為此它求助于標準 API(例如,`malloc`和`free`)來獲取和釋放內存。 ### 切換分配器 雖然編譯器默認的選擇大部分情況工作良好,也經常需要定制特定的方面。覆蓋編譯器關于使用哪個分配器的選擇可以簡單的通過鏈接到期望的分配器實現: ~~~ #![feature(alloc_system)] extern crate alloc_system; fn main() { let a = Box::new(4); // allocates from the system allocator println!("{}", a); } ~~~ 在這個例子中生成的二進制文件并不會默認鏈接到 jemalloc 而是使用了系統分配器。同理生成一個默認使用 jemalloc 的動態庫可以寫成: ~~~ #![feature(alloc_jemalloc)] #![crate_type = "dylib"] extern crate alloc_jemalloc; pub fn foo() { let a = Box::new(4); // allocates from jemalloc println!("{}", a); } # fn main() {} ~~~ ### 編寫一個自定義分配器 有時甚至 jemalloc 與系統分配器之間的選擇都是不夠的并需要一個新的自定義的分配器。這種情況你要編寫你自己實現了分配器 API(例如與`alloc_system`和`alloc_jemallo`相同)的 crate。作為一個例子,讓我們看看一個簡單的和聲明化的`alloc_system`版本: ~~~ # // only needed for rustdoc --test down below # #![feature(lang_items)] // The compiler needs to be instructed that this crate is an allocator in order // to realize that when this is linked in another allocator like jemalloc should // not be linked in #![feature(allocator)] #![allocator] // Allocators are not allowed to depend on the standard library which in turn // requires an allocator in order to avoid circular dependencies. This crate, // however, can use all of libcore. #![no_std] // Let's give a unique name to our custom allocator #![crate_name = "my_allocator"] #![crate_type = "rlib"] // Our system allocator will use the in-tree libc crate for FFI bindings. Note // that currently the external (crates.io) libc cannot be used because it links // to the standard library (e.g. `#![no_std]` isn't stable yet), so that's why // this specifically requires the in-tree version. #![feature(libc)] extern crate libc; // Listed below are the five allocation functions currently required by custom // allocators. Their signatures and symbol names are not currently typechecked // by the compiler, but this is a future extension and are required to match // what is found below. // // Note that the standard `malloc` and `realloc` functions do not provide a way // to communicate alignment so this implementation would need to be improved // with respect to alignment in that aspect. #[no_mangle] pub extern fn __rust_allocate(size: usize, _align: usize) -> *mut u8 { unsafe { libc::malloc(size as libc::size_t) as *mut u8 } } #[no_mangle] pub extern fn __rust_deallocate(ptr: *mut u8, _old_size: usize, _align: usize) { unsafe { libc::free(ptr as *mut libc::c_void) } } #[no_mangle] pub extern fn __rust_reallocate(ptr: *mut u8, _old_size: usize, size: usize, _align: usize) -> *mut u8 { unsafe { libc::realloc(ptr as *mut libc::c_void, size as libc::size_t) as *mut u8 } } #[no_mangle] pub extern fn __rust_reallocate_inplace(_ptr: *mut u8, old_size: usize, _size: usize, _align: usize) -> usize { old_size // this api is not supported by libc } #[no_mangle] pub extern fn __rust_usable_size(size: usize, _align: usize) -> usize { size } # // just needed to get rustdoc to test this # fn main() {} # #[lang = "panic_fmt"] fn panic_fmt() {} # #[lang = "eh_personality"] fn eh_personality() {} # #[lang = "eh_unwind_resume"] extern fn eh_unwind_resume() {} # #[no_mangle] pub extern fn rust_eh_register_frames () {} # #[no_mangle] pub extern fn rust_eh_unregister_frames () {} ~~~ 在我們編譯了這個 crate 之后,他可以被如下使用: ~~~ extern crate my_allocator; fn main() { let a = Box::new(8); // allocates memory via our custom allocator crate println!("{}", a); } ~~~ ### 自定義分配器的限制 使用自定義分配器時要滿足一些限制,否則可能導致編譯器錯誤: - 任何一個程序只能鏈接到一個分配器。二進制、動態庫和靜態庫必須正好鏈接到一個分配器上,并且,如果沒有顯式選擇,編譯器會選擇一個。另一方面,rlib 并不需要鏈接到一個分配器(不過仍然可以)。 - 一個標記為`#![needs_allocator]`(例如,目前的`liballoc`)的分配器使用者和一個`#[allocator]` crate 不能直接依賴一個需要分配器的 crate(例如,循環引用是不允許的)。這基本上意味著目前分配器必須依賴 libcore。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看