joonspk-research / generative_agents

Generative Agents: Interactive Simulacra of Human Behavior
Apache License 2.0
16.22k stars 2.08k forks source link

Memory leak in frontend? #137

Closed nyoma-diamond closed 8 months ago

nyoma-diamond commented 8 months ago

Running a large number of steps (e.g., run 100) grinds to a halt due to what appears to be a memory leak somewhere in the frontend code. Something appears to be collecting which causes each step to take longer than the previous as memory accumulates (multiple gigabytes worth). The memory builds in the browser process.

On Chrome I get a huge number of net::ERR_INSUFFICIENT_RESOURCES errors after running for a couple of minutes. Firefox does not report insufficient resources, but does slow down significantly as more memory builds up, causing Generative Agents to slow down while it waits for the frontend to update.

I am attempting to find the cause of this problem, but haven't been able to. Has anyone else noticed this?

nyoma-diamond commented 8 months ago

Solution found!

Update: The cause of this problem is because the framerate of the frontend simulation in browser is unrestricted. The frontend runs the update code every frame, causing a network request every frame as well. By default Phaser will use the refresh rate of your monitor as the target framerate, so if your refresh rate is too high you end up producing more network requests than the browser can physically handle. This is especially the case when the system running the frontend and backend are remote while the browser you are opening the simulator with is local, as a huge number of network requests can easily get bottlenecked. In Firefox, this causes all the requests to get loaded into memory, causing what appeared to be a memory leak. In Chrome, some of the requests get loaded into memory before being kicked back with an ERR_INSUFFICIENT_RESOURCES error.

Solution: in main_script.html, you can set a framerate cap in the Phaser config using this:

fps: {
    target: [[your desired refresh rate]],
    forceSetTimeOut: true
}

So my config variable looks like this:

// Phaser 3.0 global settings. 
// Configuration meant to be passed to the main Phaser game instance. 
const config = {
    type: Phaser.AUTO,
    width: 1500,
    height: 800,
    parent: "game-container",
    pixelArt: true,
    physics: {
        default: "arcade",
        arcade: {
            gravity: { y: 0 }
        }
    },
    scene: {
    preload: preload,
    create: create,
        update: update
    },
    fps: {
         target: 15,
         forceSetTimeOut: true
    }
};
nyoma-diamond commented 8 months ago

forgot to close; my bad :p