├── README.md
├── index.html
├── script.js
└── style.css
/README.md:
--------------------------------------------------------------------------------
1 | # Memory Management Simulator
2 | An online simulation of operating system memory management to help computer science students understand the algorithm in a visual way.
3 |
4 | * Users can input processes of a given size and length of time.
5 | * Each process is automatically allocated to a ‘chunk’ in memory (as would be
6 | done by an operating system).
7 | * Memory chunks are partitioned for efficient process allocation (using the
8 | ‘Best-Fit’ strategy to reduce fragmentation).
9 | * As the program runs, a clock ticks in the background, decrementing the time
10 | remaining for each process.
11 | * When a process terminates, chunks are automatically deallocated (freeing
12 | memory).
13 | * Memory is simulated using a doubly linked list data structure.
14 |
15 | 
16 |
17 | ### Demo
18 | A live version can be found here:
19 | [Memory Management Simulator](http://jamiegoodson.uk/projects/memory-management-simulator/)
20 |
21 | 
22 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
Memory Management
An Online Simulation
12 |
13 |
14 |
19 |
20 |
21 |
Add Process
22 |
27 |
28 |
Process Queue
29 |
30 | Process ID | Size (K) | Time Units Remaining |
31 |
32 |
33 |
34 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/script.js:
--------------------------------------------------------------------------------
1 | function Process(size, time) {
2 | this.size = size;
3 | this.timeLeft = time;
4 | this.allocatedBlock = null;
5 | this.id = processID;
6 |
7 | processID += 1;
8 |
9 | this.isAllocated = function() {
10 | return this.allocatedBlock != null;
11 | };
12 |
13 | this.tick = function() {
14 | this.timeLeft -=1;
15 | };
16 | };
17 |
18 | function MemControlBlock(size) {
19 | this.size = size;
20 | this.process = null;
21 | this.available = true;
22 | this.next = null;
23 | this.prev = null;
24 | this.fromPartition = false; // Used to determine whether height of a MemControlBlock needs to be added
25 |
26 | this.setProcess = function(process) {
27 | if (process == null) {
28 | this.process = null;
29 | this.available = true;
30 | } else {
31 | this.process = process;
32 | this.available = false;
33 | };
34 | };
35 | };
36 |
37 | // Simulates memory
38 | function Heap() {
39 | this.head = null;
40 | this.size = 0;
41 |
42 | // Allocate process to memory.
43 | // Use best-fit method: from the list of holes, choose the smallest hole
44 | this.requestAllocation = function(process) {
45 | blockBestFit = this.head;
46 |
47 | // Make sure our initial best block is valid
48 | while ((blockBestFit.size < process.size) || (!blockBestFit.available)) {
49 | blockBestFit = blockBestFit.next;
50 | if (blockBestFit == null) {return false}; // Means we couldn't even find an initial valid block
51 | };
52 | //log("Initial best block: " + blockBestFit.size);
53 |
54 | // See if there's an even better block
55 | block = blockBestFit.next;
56 | while (block != null) {
57 | //log("Testing block: " + block.size);
58 | if ((block.size >= process.size) && (block.available) && (block.size < blockBestFit.size)) {
59 | blockBestFit = block;
60 | //log("New best block: " + blockBestFit.size);
61 | };
62 | block = block.next;
63 | };
64 |
65 | spaceLeftover = blockBestFit.size - (process.size + memControlBlockSize); // Space leftover if block was divided
66 |
67 | // Partition block if needed
68 | if (spaceLeftover > 0) {
69 | newBlock = new MemControlBlock(spaceLeftover);
70 |
71 | nextBlock = blockBestFit.next;
72 | if (nextBlock != null) {
73 | nextBlock.prev = newBlock;
74 | newBlock.next = nextBlock;
75 | };
76 |
77 | blockBestFit.next = newBlock;
78 | newBlock.prev = blockBestFit;
79 |
80 | blockBestFit.size = process.size;
81 |
82 | newBlock.fromPartition = true;
83 | };
84 |
85 | blockBestFit.setProcess(process);
86 | process.allocatedBlock = blockBestFit;
87 | return true;
88 | };
89 |
90 | this.deallocateProcess = function(process) {
91 | process.allocatedBlock.setProcess(null);
92 | process.allocatedBlock = null;
93 | };
94 |
95 | this.add = function(block) {
96 | if (this.head == null) {
97 | this.head = block;
98 | } else {
99 | block.next = this.head;
100 | this.head.prev = block;
101 | this.head = block;
102 | };
103 |
104 | this.size += block.size;
105 | }
106 |
107 | this.toString = function() {
108 | string = "[|";
109 | block = this.head;
110 |
111 | prefix = "";
112 | suffix = " |";
113 | while (block != null) {
114 | if (block.available) {prefix = "