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] session memory usage #1148

Closed
BohuTANG opened this issue Jul 22, 2021 · 8 comments · Fixed by #2299 or #2356
Closed

[memory] session memory usage #1148

BohuTANG opened this issue Jul 22, 2021 · 8 comments · Fixed by #2299 or #2356
Assignees
Labels
C-feature Category: feature C-manageability Category: management for databend, api or others community-take good first issue Category: good first issue

Comments

@BohuTANG
Copy link
Member

Summary

Use rust custom allocator trait to track the session memory usage.

@BohuTANG BohuTANG added C-feature Category: feature C-manageability Category: management for databend, api or others labels Jul 22, 2021
@BohuTANG BohuTANG added this to the v0.5 milestone Jul 22, 2021
@zhang2014 zhang2014 added the good first issue Category: good first issue label Jul 27, 2021
@PsiACE
Copy link
Member

PsiACE commented Aug 29, 2021

fyi, custom allocator for tracing memory usage:

use std::alloc::System;
use std::alloc::{GlobalAlloc, Layout};
use std::sync::atomic::{AtomicU64, Ordering};

pub struct Trallocator(System, AtomicU64, AtomicU64);

unsafe impl GlobalAlloc for Trallocator {
    unsafe fn alloc(&self, l: Layout) -> *mut u8 {
        self.1.fetch_add(l.size() as u64, Ordering::SeqCst);
        self.2.fetch_add(l.size() as u64, Ordering::SeqCst);
        self.0.alloc(l)
    }
    unsafe fn dealloc(&self, ptr: *mut u8, l: Layout) {
        self.0.dealloc(ptr, l);
        self.1.fetch_sub(l.size() as u64, Ordering::SeqCst);
    }
}

impl Trallocator {
    pub const fn new(s: System) -> Self {
        Trallocator(s, AtomicU64::new(0), AtomicU64::new(0))
    }

    pub fn reset(&self) {
        self.1.store(0, Ordering::SeqCst);
        self.2.store(0, Ordering::SeqCst);
    }

    pub fn get(&self) -> u64 {
        self.1.load(Ordering::SeqCst)
    }

    pub fn get_sum(&self) -> u64 {
        self.2.load(Ordering::SeqCst)
    }
}

@Veeupup
Copy link
Collaborator

Veeupup commented Oct 13, 2021

/assignme

@Veeupup
Copy link
Collaborator

Veeupup commented Oct 13, 2021

@BohuTANG @PsiACE
I just investigated the method to implement this issue and I found that maybe we can not implement it now.
Here is my solution:

  1. implement a alloctor that implements Alloctor trait rather than GlobalAlloc trait, because GlobalAlloc will use #[global_alloctor] and it will make all heap memory allocate from this alloctor(And for now we just want to track Session)
  2. And then, we can use Box::new_in to allocate a session when creating, like
let allocator = MyAllocator::new(System); // which implement `std::alloc::Allocator` trait
let session = Box::new_in(Session::try_create(...), allocator); // compile error ❌

but for now, the box allocate_api is not stable and has bug.
When I am coding as aboved, compiler will give error output and I found that there is a bug now, see issue78459 . I encounter the same problem.

So, I think now this way is not going to be okay for this issue.


btw, I check it that we can use constom allocator for Vec normally, but now ok for Box

let allocator = MyAllocator::new(System); // which implement `std::alloc::Allocator` trait
let mut item: Vec<String, Trallocator> = Vec::new_in(allocator); // it works ok ✅

@BohuTANG
Copy link
Member Author

Thank you @Veeupup for the work.
The task doesn't look that easy and we need to think long about it.

@BohuTANG
Copy link
Member Author

BohuTANG commented Oct 16, 2021

@Veeupup
We should not use the global alloc here since we want to track per session memory usage. servo has a good idea, this may helpful:
https://github.com/servo/servo/blob/master/components/malloc_size_of/lib.rs

@Veeupup
Copy link
Collaborator

Veeupup commented Oct 16, 2021

@Veeupup We should not use the global alloc here since we want to track per session memory usage. servo has a good idea, this may helpful: https://github.com/servo/servo/blob/master/components/malloc_size_of/lib.rs

Thanks for guiding, I will try to learn something from it.

@Veeupup
Copy link
Collaborator

Veeupup commented Oct 17, 2021

@BohuTANG hi, I have figured it that servo use jemalloc_sys as global allocator and then use malloc_size_of.rs to implement some trait as MallocOfSize(related to jemalloc_sys funcs) to get all memory usage which interests.

And now I encountered a problem that I'm not very clear about what session memory usage exactly means.

  1. Does it mean that only memory about a session struct itself ? such as member variable memory usage and its inner function memory usage.
    or
  2. Does it mean that all memory usage when a session involved(from a session created to where it ended), such as mysql server involved, sql parser's work, physical plan executed and more...(it maybe complicated that not that easy to trace all memory it involved)

@BohuTANG
Copy link
Member Author

I guess here we only tracking the session object(malloc_size_of(&session)) is ok, but not sure it works or not, have found some useful tests:
https://github.com/tetcoin/tetsy-common/blob/ac34ab6549f05849fe6e1f636445d151044981fe/tetsy-util-mem/tests/derive.rs#L56

In this example, it can track a more complex struct

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-feature Category: feature C-manageability Category: management for databend, api or others community-take good first issue Category: good first issue
Projects
None yet
5 participants