Memory Management

Part 1 Objectives

  • Define reference types
    • Partially review, but hopefully this gives you a deeper understanding of why reference types behave the way they do.
  • Describe a pointer
  • Draw a memory diagram

Registers and Memory

Computers have two ways to store data. Registers and Memory.

 

variables, objects, and everything in a computer program is an abstraction around these mechanisms.

Registers

  • Registers are very small - each one can store 64 bits
     
  • Registers exist on the processor chip
     
  • Data must be loaded into registers before the processor can use it

Memory

  • All non-register storage can be considered memory
     
  • L1-L4 caches, RAM, and hard-disc space are ALL in memory

L1 cache

L2 cache

L3 cache

RAM

Hard Disk

The Processor and the Registers

Memory

"Memory"

Although there are some limitations to this mindset, for now we are going to treat *all* of memory as one big bucket

Memory & Programs

Throughout the life-cycle of a program, data moves between memory and registers.

 

 

"Memory"

Memory & Programs

Because registers have limited storage, data that exceeds the limit must live in memory.

 

In JavaScript each integer is 64 bits. This array is therefore (at least) 5 times to large for a register.

var x = [1, 2, 3, 4, 5];

Memory & Programs

So our register gets a pointer to a memory address

var x = [1, 2, 3, 4, 5];

x = 0xFF019A

0xFF019A:

0: 1

1: 2

2: 3

3: 4

4: 5

Memory & Programs

x = 0xFF019A

0xFF019A:

0: 1

1: 2

2: 3

3: 4

4: 5

Hold up: Whats this?

Memory & Programs

This pointer is why Objects are called reference types. Our variable really holds a 64-bit pointer to a memory address

var x = [1, 2, 3, 4, 5];

x = 0xFF019A

0xFF019A:

0: 1

1: 2

2: 3

3: 4

4: 5

Memory & Programs

If we make a new variable and set it equal to x, this variable references the same memory location.

var x = [1, 2, 3, 4, 5];
var y = x;

x = 0xFF019A

0xFF019A:

0: 1

1: 2

2: 3

3: 4

4: 5

y = 0xFF019A

Memory & Programs

If we change one of the properties at that location both variables reflect the change.

x[0] = 100;
console.log(y[0]); // Prints 100

x = 0xFF019A

0xFF019A:

0: 100

1: 2

2: 3

3: 4

4: 5

y = 0xFF019A

Memory & Programs

But if we change what one of the variables points to then the modified variable points somewhere new.

y = [7,8,9]
console.log(y[0]); // Prints 7
console.log(x[0]); // Still prints 100

x = 0xFF019A

0xFF019A:

0: 100

1: 2

2: 3

3: 4

4: 5

y = 0xFF0EEE

0xFF0EEE:

0: 7

1: 8

2: 9

 

Lets Examine

http://pythontutor.com

Memory & Programs

If all our registers are filled, even 64 bit primitive types may have to be stored into memory and fetched again when they are needed.

 

There is *a lot* of hardware and software that we rely on to handle this for us, and our mental model doesn't need to be perfect.

 

(and probably couldn't be without years of study in Computer Engineering, Computer Science, and Operating Systems)

Memory Diagrams

Lets go here https://github.com/gSchool/computer-science-curriculum/blob/master/Unit-0/02-memory-diagrams.md

 

And look at some "memory diagrams" before we create some ourselves.

 

Stop when you get to "Prototypes" -- we'll discuss those later.

 

Take 10 minutes right now to read this

 

Now, Practice

Objectives Review

  • Define reference types
  • Describe a pointer
  • Draw a memory diagram

g35 Specific Slide

You all asked about Symbols, the new ES2016 (aka JavaScript 6) primitive type.

 

Now we have enough information to better understand Symbols.

var fooOne = new Symbol('foo');
var fooTwo = new Symbol('foo');

'foo' === 'foo'    // this evaluates to true
fooOne === fooTwo; // What do you think this evaluates to?

// Why? 

Objectives Part 2

  • Describe "The Stack" and what data lives there
  • Describe "The Heap" and what data lives there
  • Describe "Garbage Collection" at a high level
     
  • Stretch goal - appreciate how many countless hours of frustration John McCarthy has saved us all by inventing Garbage Collection.

Memory Groups

  • Computer programs use two groupings for memory
     
  • The distinction between these is 100% software - both use the same memory hardware
     
  • They are called "The Stack" and "The Heap"

The Stack

  • The Stack is for localized program memory
     
  • Every time a function is called, space is allocated on the stack
     
  • This "Stack Frame" contains local variables and pointers to function calls as well as "return addresses"
     
  • Once a frame "pops off the stack" it is immediately freed as memory space.

The Stack

Learn by example

function fun1() {
    var a = 1;
    var b = 2;
    return fun2(a, b);
}

function fun2(x, y) {
    var c = x + y;
    return c;
}

fun1();

We have the code to the left. Two functions are defined, then we call fun1.

The Stack

At the "top level" we're on whats called the global frame. Before anything happens, it's empty.

// YOU ARE HERE
function fun1() {
    var a = 1;
    var b = 2;
    return fun2(a, b);
} 

function fun2(x, y) {
    var c = x + y;
    return c;
}

fun1();
Global Frame:
returnTo: null

Every stack frame knows where it was called from. The global stack frame is special in that it isn't called from anywhere.

The Stack

After we execute the two function definitions, our stack looks like this

function fun1() {
    var a = 1;
    var b = 2;
    return fun2(a, b);
} 

function fun2(x, y) {
    var c = x + y;
    return c;
}

// YOU ARE HERE
fun1();
Global Frame:
fun1: pointer to memory address
fun2: pointer to memory address
returnTo: null

The Stack

Calling fun1 adds a new frame

function fun1() {
    // YOU ARE HERE
    var a = 1;
    var b = 2;
    return fun2(a, b);
} 

function fun2(x, y) {
    var c = x + y;
    return c;
}

fun1();
fun1 Frame:
returnTo: Global Frame
Global Frame:
fun1: pointer to memory address
fun2: pointer to memory address
returnTo: null

The Stack

Local variables go onto the frame line by line

function fun1() {
    var a = 1;
    var b = 2;
    // YOU ARE HERE
    return fun2(a, b);
} 

function fun2(x, y) {
    var c = x + y;
    return c;
}

fun1();
fun1 Frame:
a: 1, b: 2
returnTo: Global Frame
Global Frame:
fun1: pointer to memory address
fun2: pointer to memory address
returnTo: null

The Stack

Calling fun2 adds a new frame, parameters are already on the stack when they are passed in.

function fun1() {
    var a = 1;
    var b = 2;
    return fun2(a, b);
} 

function fun2(x, y) {
    // YOU ARE HERE
    var c = x + y;
    return c;
}

fun1();
fun2 Frame:
x: 1, y:2
returnTo: fun1 frame
fun1 Frame:
a: 1, b: 2
returnTo: Global Frame
Global Frame:
fun1: pointer to memory address
fun2: pointer to memory address
returnTo: null

The Stack

c gets added after x+y is computed

function fun1() {
    var a = 1;
    var b = 2;
    return fun2(a, b);
} 

function fun2(x, y) {
    var c = x + y;
    // YOU ARE HERE
    return c;
}

fun1();
fun2 Frame:
c: 3, x: 1, y:2
returnTo: fun1 frame
fun1 Frame:
a: 1, b: 2
returnTo: Global Frame
Global Frame:
fun1: pointer to memory address
fun2: pointer to memory address
returnTo: null

The Stack

Return pops the top stack frame off the stack and sends execution back to the caller

function fun1() {
    var a = 1;
    var b = 2;
    return fun2(a, b);
    // YOU ARE ABOVE
} 

function fun2(x, y) {
    var c = x + y;
    return c;
}

fun1();
fun1 Frame:
a: 1, b: 2, tmpVal: 3
returnTo: Global Frame
Global Frame:
fun1: pointer to memory address
fun2: pointer to memory address
returnTo: null

The Stack

Return pops the top stack frame off the stack and sends execution back to the caller

function fun1() {
    var a = 1;
    var b = 2;
    return fun2(a, b);
} 

function fun2(x, y) {
    var c = x + y;
    debugger;
    return c;
}

fun1(); // Returning to here now
Global Frame:
fun1: pointer to memory address
fun2: pointer to memory address
tmpVal: 3
returnTo: null

After this, the program terminates.

The Heap

  • The Heap is for general data storage.
     
  • ALL Objects are stored on the heap.
     
  • There is no storage pattern enforcement (unlike the stack which is a data-structure called a stack).
     
  • We rely on "garbage collection" to free memory on the heap.

The Heap

function fun1() {
    var a = {
        p1: 1,
        p2: "text",
    };
    return a;
}

var b = fun1();
debugger;

... somewhere in the heap ...

p1: a
p2: "text"

The Stack will contain the value for b -- which is a pointer to this data somewhere in the heap!

Garbage Collection

Because the heap doesn't have a specific pattern for memory allocation, we have to do more work to "free" the memory allocated.

Garbage Collection

In older languages, this was done manually by programmers!

   char *str;

   /* Initial memory allocation */
   str = (char *) malloc(15);

   /* Reallocating memory */
   str = (char *) realloc(str, 25);

   /* Free the space */
   free(str);

Garbage Collection

In modern languages a separate program called "the garbage collector" periodically searches for objects that no longer have any pointers pointing at them

function fun1() {
    var a = {
        p1: 1,
        p2: "text",
    };
    return a;
}

console.log(fun1());
// At this point there is
// no way to access 'a'

Garbage Collection

After the console.log statement completes, there is no reference to the object we called 'a'. The Garbage Collector will find it, and free it's space on the heap.

function fun1() {
    var a = {
        p1: 1,
        p2: "text",
    };
    return a;
}

console.log(fun1());

... somewhere in the heap ...

p1: a
p2: "text"

Garbage Collection

After the console.log statement completes, there is no reference to the object we called 'a'. The Garbage Collector will find it, and free it's space on the heap.

function fun1() {
    var a = {
        p1: 1,
        p2: "text",
    };
    return a;
}

console.log(fun1());

... somewhere in the heap ...

Questions?

Memory Management

By Tyler Bettilyon

Memory Management

  • 1,685