Memory leaks as hell

I start writing an app using Pison, and I found that my PC freezes in few seconds after my app run because memory is all gone.

I reduced app to the very small example, and I can't understand where memory goes.

Here it is. If you uncomment texture.update it hogs all memory (gigabytes of it!) in seconds.

extern crate piston_window;
extern crate image as im;

use piston_window::*;
use piston::event_loop::Events;

fn main() {
    let x = 1920;
    let y  = 1080;
    let opengl = OpenGL::V3_2;
    let mut window: PistonWindow =
        WindowSettings::new("test", (x, y))
    let mut texture_context = TextureContext {
        factory: window.factory.clone(),
        encoder: window.factory.create_command_buffer().into()
    let mut events = Events::new(EventSettings::new().lazy(false));
    let buf = im::ImageBuffer::new(x, y);
    let mut texture: G2dTexture = Texture::from_image(
                &mut texture_context,
    while let Some(e) = window) {
        if let Some(_) = e.render_args() {
            // texture.update(&mut texture_context, &buf).unwrap();
            window.draw_2d(&e, |c, g, _device| {
                    image(&texture, c.transform, g);

How can it be that memory is leaking?

If you're on Linux, you can see what's leaking with Valgrind's memcheck. It's compatible with Rust.


My guess would be that the texture updates are queued into some staging buffer which is never flushed or reused. Leaking ~8MB per frame will quickly fill up memory. I don't know enough about this specific API to say for sure, or how to avoid it, though.

1 Like

Thank you for idea. I've run valgrind, it sees huge allocated memory, but only 305,761 bytes leaked.

The single thing I see (I don't know if this matter or not) is this:

==9763== Conditional jump or move depends on uninitialised value(s)
==9763==    at 0x7494B24: ??? (in /usr/lib/x86_64-linux-gnu/

It's easy to point to nvidia and claim they leaks memory, but the leak is crazy (like 16Gb in 20 seconds) so I doubt they are real culprit here.

draw_2d already does nothing when e.render_args() is None.

1 Like

For what it's worth, I can reproduce this leak. Since you have a reproducible test case, I would report this to the Piston or gfx issue tracker.

1 Like

Thank you, I've reported it here:


After some example rereading, I've realized, I trimmed away from examples one important line:


So, the proper draw_2d function is

        if let Some(_) = e.render_args() {
            texture.update(&mut texture_context, &buf).unwrap();
            window.draw_2d(&e, |c, g, device| {
                    image(&texture, c.transform, g);

It completely stopped memory leak.


Very interesting. I found (after I fixed memory leak I've complained about) that if I do window.draw_2d on empty events it bumps my memory consumption about 10 fold. It's not leaking, but application is consuming a lot of CPU and memory, so this if is very important for performance.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.