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

"Leaky" memory usage when using repeat_infinite() #673

Open
Pmyl opened this issue Jan 9, 2025 · 4 comments
Open

"Leaky" memory usage when using repeat_infinite() #673

Pmyl opened this issue Jan 9, 2025 · 4 comments
Labels

Comments

@Pmyl
Copy link

Pmyl commented Jan 9, 2025

Hello,
I'm using Rodio for my application and I'd like for my music to repeat multiple times. I've found the repeat_infinite() function for the Source struct but when I monitored the memory usage I've found out that it's growing about at 10mb every 15 seconds.

I haven't checked if it eventually caps, I only saw that it went from 30mb of memory to 100mb+.

Not using repeat_infinite() works as intended, the memory usage doesn't move.

In my app I create a Sink and I append the Decoder wrapping my music. I assumed that the problem was about buffering more and more music, but in my case the music is in a Cursor<Vec<u8>> so it shouldn't load any more of it (plus my music file is definitely less than 70mb).

System:
OS: Linux X11 pop 22.04
Memory: 61.9 GiB
Architecture: x86_64
GPU: NVIDIA GeForce RTX 4070 || NVIDIA || 560.35.03

Relevant crates:
cpal = "0.15.3"
rodio = "0.20.1"

@dvdsk
Copy link
Collaborator

dvdsk commented Jan 9, 2025

for my fellow maintainers, the repeat code in rodio:
source/mod.rs

    fn repeat_infinite(self) -> Repeat<Self>
    where
        Self: Sized,
    {
        repeat::repeat(self)
    }

source/repeat.rs

pub fn repeat<I>(input: I) -> Repeat<I>
where
    I: Source,
    I::Item: Sample,
{
    let input = input.buffered();
    Repeat {
        inner: input.clone(),
        next: input,
    }
}

source/repeat.rs specifically impl Iterator

    #[inline]
    fn next(&mut self) -> Option<<I as Iterator>::Item> {
        if let Some(value) = self.inner.next() {
            return Some(value);
        }

        self.inner = self.next.clone();
        self.inner.next()
    }

This all looks fine so its probably an issue in bufferd's clone impl.

@dvdsk
Copy link
Collaborator

dvdsk commented Jan 9, 2025

@Pmyl I assume you do something like this?

    let music = Decoder::new(BufReader::new(file)?)
    let infinite = music.repeat_infinite() ; 
    sink.append(source)

@dvdsk
Copy link
Collaborator

dvdsk commented Jan 9, 2025

I'll be honest I find buffered rather complex, might need a rewrite/refactor. I'm still researching the f32 pipeline so for now I can not take this on.

@dvdsk dvdsk added the bug label Jan 9, 2025
@Pmyl
Copy link
Author

Pmyl commented Jan 10, 2025

@Pmyl I assume you do something like this?

    let music = Decoder::new(BufReader::new(file)?)
    let infinite = music.repeat_infinite() ; 
    sink.append(source)

Just a small correction but yes

let music = Decoder::new(BufReader::new(file)?)
let infinite = music.repeat_infinite() ; 
sink.append(infinite)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants