nand2tetris / web-ide

A web-based IDE for https://nand2tetris.org
https://nand2tetris.github.io/web-ide
Other
85 stars 22 forks source link

[bug]: Object allocation/deallocation creates memory leaks #452

Closed happytomatoe closed 2 months ago

happytomatoe commented 2 months ago

Tool

VM Emulator

Interface

Website (https://nand2tetris.github.io/web-ide)

Contact Details

No response

What happened?

Hi! When I try to run next code at maximum speed I get Program exited with error code 6: Heap overflow (Memory.alloc). Is this expected? When I allocate/dispone Array with ints everything works.

class Main {
    function void main() {
        var int   i,j;
        var Cactus c;
        var Array r;

        let i=0;

        while(i<1000){
            let r=Array.new(8000);
            let j=0;
            while(j<8000){
                let r[j]=Cactus.new(false);
                let j=j+1;
            }
            let j=0;
            while(j<8000){
                let c= r[j];
                do c.dispose();
                let j=j+1;
            }
            do r.dispose();
            let i=i+1;
        }
        do Output.printString("Finished");
        return;
    }
}
class Cactus {
  field boolean visible;

  constructor Cactus new(boolean visible_) {
    let visible=visible_;

    return this;
}

method void dispose() {
  do Memory.deAlloc(visible);
  do Memory.deAlloc(this);
  return;
}

}

Additional Comments

No response

Do you want to try to fix this bug?

Code of Conduct

DavidSouther commented 2 months ago

@happytomatoe Thank you for opening this issue.

Is this expected

I'm going to say that it looks like you're stress testing the NAND2Tetris system beyond what we've done at this point! Well done! :)

Jack as a language is designed as a teaching language, not a memory safe high performance language. Reading this code, you create an array with 8000 elements (that is, allocate 8000 pointers), then attempt to create 8000 instances of a class with one field, so you have 1x Memory.alloc(8000) + 8000x Memory.alloc(1). The default memory allocator IIRC uses a naive linked list to track fee segments, so there's an additional "byte" per alloc, for an expected total allocation in this program of 24,001, however, HEAP_SIZE in the Hack VM is 14,336 items.

So, yes, this is "expected behavior".