The Second Chance Page Replacement Algorithm is an improvement over FIFO that avoids removing frequently used pages by using a reference bit. When a page is accessed, its reference bit is set to 1, and during replacement, pages with bit 0 are replaced while pages with bit 1 are given a second chance, making memory management more efficient.
- Uses a reference bit to track page usage
- Replaces pages with reference bit 0
- Gives a second chance to pages with bit 1 by resetting it
- More efficient and scalable than FIFO, and sometimes better than LRU in modern systems
Algorithm
The algorithm works by associating a reference bit with each page in memory:
- Reference Bit = 1, The page has been recently used.
- Reference Bit = 0, The page has not been recently used.
Steps:
1. Pages are maintained in a queue (like FIFO).
2. When a page fault occurs, the algorithm checks the page at the front of the queue.
3. If the reference bit = 0, the page is replaced.
4. If the reference bit = 1:
- The reference bit is reset to 0.
- The page is moved to the back of the queue (given a second chance).
- The search continues until a page with reference bit = 0 is found.
Thus, frequently accessed pages are less likely to be replaced.
Example
Let's say the reference string is 0 4 1 4 2 4 3 4 2 4 0 4 1 4 2 4 3 4 and we have 3 frames. Let's see how the algorithm proceeds by tracking the second chance bit and the pointer.

- Initially, all frames are empty so after the first 3 passes they will be filled with {0, 4, 1} and the second chance array will be {0, 0, 0} as none has been referenced yet. Also, the pointer will cycle back to 0.
- Pass-4: Frame={0, 4, 1}, second_chance = {0, 1, 0} [4 will get a second chance], pointer = 0 (No page needed to be updated so the candidate is still page in frame 0), pf = 3 (No increase in page fault number).
- Pass-5: Frame={2, 4, 1}, second_chance= {0, 1, 0} [0 replaced; it's second chance bit was 0, so it didn't get a second chance], pointer=1 (updated), pf=4
- Pass-6: Frame={2, 4, 1}, second_chance={0, 1, 0}, pointer=1, pf=4 (No change)
- Pass-7: Frame={2, 4, 3}, second_chance= {0, 0, 0} [4 survived but it's second chance bit became 0], pointer=0 (as element at index 2 was finally replaced), pf=5
- Pass-8: Frame={2, 4, 3}, second_chance= {0, 1, 0} [4 referenced again], pointer=0, pf=5
- Pass-9: Frame={2, 4, 3}, second_chance= {1, 1, 0} [2 referenced again], pointer=0, pf=5
- Pass-10: Frame={2, 4, 3}, second_chance= {1, 1, 0}, pointer=0, pf=5 (no change)
- Pass-11: Frame={2, 4, 0}, second_chance= {0, 0, 0}, pointer=0, pf=6 (2 and 4 got second chances)
- Pass-12: Frame={2, 4, 0}, second_chance= {0, 1, 0}, pointer=0, pf=6 (4 will again get a second chance)
- Pass-13: Frame={1, 4, 0}, second_chance= {0, 1, 0}, pointer=1, pf=7 (pointer updated, pf updated)
- Page-14: Frame={1, 4, 0}, second_chance= {0, 1, 0}, pointer=1, pf=7 (No change)
- Page-15: Frame={1, 4, 2}, second_chance= {0, 0, 0}, pointer=0, pf=8 (4 survived again due to 2nd chance!)
- Page-16: Frame={1, 4, 2}, second_chance= {0, 1, 0}, pointer=0, pf=8 (2nd chance updated)
- Page-17: Frame={3, 4, 2}, second_chance= {0, 1, 0}, pointer=1, pf=9 (pointer, pf updated)
- Page-18: Frame={3, 4, 2}, second_chance= {0, 1, 0}, pointer=1, pf=9 (No change)
Code Implementation:
#include<iostream>
#include<cstring>
#include<sstream>
using namespace std;
// If page found, updates the second chance bit to true
static bool findAndUpdate(int x,int arr[],
bool second_chance[],int frames){
int i;
for(i = 0; i < frames; i++){
if(arr[i] == x){
// Mark that the page deserves a second chance
second_chance[i] = true;
// Return 'true', that is there was a hit
// and so there's no need to replace any page
return true;
}
}
// Return 'false' so that a page for replacement is selected
// as he reuested page doesn't exist in memory
return false;
}
// Updates the page in memory and returns the pointer
static int replaceAndUpdate(int x,int arr[],
bool second_chance[],int frames,int pointer){
while(true){
// We found the page to replace
if(!second_chance[pointer]){
// Replace with new page
arr[pointer] = x;
// Return updated pointer
return (pointer + 1) % frames;
}
// Mark it 'false' as it got one chance
// and will be replaced next time unless accessed again
second_chance[pointer] = false;
//Pointer is updated in round robin manner
pointer = (pointer + 1) % frames;
}
}
static void printHitsAndFaults(string reference_string, int frames){
int pointer, i, l=0, x, pf;
//initially we consider frame 0 is to be replaced
pointer = 0;
//number of page faults
pf = 0;
// Create a array to hold page numbers
int arr[frames];
// No pages initially in frame,
// which is indicated by -1
memset(arr, -1, sizeof(arr));
// Create second chance array.
// Can also be a byte array for optimizing memory
bool second_chance[frames];
// Split the string into tokens,
// that is page numbers, based on space
string str[100];
string word = "";
for (auto x : reference_string){
if (x == ' '){
str[l]=word;
word = "";
l++;
}
else{
word = word + x;
}
}
str[l] = word;
l++;
// l=the length of array
for(i = 0; i < l; i++){
x = stoi(str[i]);
// Finds if there exists a need to replace
// any page at all
if(!findAndUpdate(x,arr,second_chance,frames)){
// Selects and updates a victim page
pointer = replaceAndUpdate(x,arr,
second_chance,frames,pointer);
// Update page faults
pf++;
}
}
cout << "Total page faults were " << pf << "\n";
}
// Driver code
int main(){
string reference_string = "";
int frames = 0;
// Test 1:
reference_string = "0 4 1 4 2 4 3 4 2 4 0 4 1 4 2 4 3 4";
frames = 3;
// Output is 9
printHitsAndFaults(reference_string,frames);
// Test 2:
reference_string = "2 5 10 1 2 2 6 9 1 2 10 2 6 1 2 1 6 9 5 1";
frames = 4;
// Output is 11
printHitsAndFaults(reference_string,frames);
return 0;
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// If page found, updates the second chance bit to true
static int findAndUpdate(int x, int arr[], int second_chance[], int frames) {
int i;
for (i = 0; i < frames; i++) {
if (arr[i] == x) {
// Mark that the page deserves a second chance
second_chance[i] = 1;
// Return 'true', that is there was a hit
// and so there's no need to replace any page
return 1;
}
}
// Return 'false' so that a page for replacement is selected
// as the requested page doesn't exist in memory
return 0;
}
// Updates the page in memory and returns the pointer
static int replaceAndUpdate(int x, int arr[], int second_chance[], int frames, int pointer) {
while (1) {
// We found the page to replace
if (!second_chance[pointer]) {
// Replace with new page
arr[pointer] = x;
// Return updated pointer
return (pointer + 1) % frames;
}
// Mark it 'false' as it got one chance
// and will be replaced next time unless accessed again
second_chance[pointer] = 0;
// Pointer is updated in round robin manner
pointer = (pointer + 1) % frames;
}
}
static void printHitsAndFaults(char* reference_string, int frames) {
int pointer = 0, i, l = 0, x, pf = 0;
// Create a array to hold page numbers
int arr[frames];
// No pages initially in frame, which is indicated by -1
memset(arr, -1, sizeof(arr));
// Create second chance array
int second_chance[frames];
// Split the string into tokens, that is page numbers, based on space
char* token = strtok(reference_string, " ");
while (token != NULL) {
str[l++] = atoi(token);
token = strtok(NULL, " ");
}
for (i = 0; i < l; i++) {
x = str[i];
// Finds if there exists a need to replace any page at all
if (!findAndUpdate(x, arr, second_chance, frames)) {
// Selects and updates a victim page
pointer = replaceAndUpdate(x, arr, second_chance, frames, pointer);
// Update page faults
pf++;
}
}
printf("Total page faults were %d\n", pf);
}
int main() {
char reference_string[] = "0 4 1 4 2 4 3 4 2 4 0 4 1 4 2 4 3 4";
int frames = 3;
// Output is 9
printHitsAndFaults(reference_string, frames);
strcpy(reference_string, "2 5 10 1 2 2 6 9 1 2 10 2 6 1 2 1 6 9 5 1");
frames = 4;
// Output is 11
printHitsAndFaults(reference_string, frames);
return 0;
}
import java.util.Arrays;
public class SecondChance{
static boolean findAndUpdate(int x, int[] arr, boolean[] secondChance, int frames){
for (int i = 0; i < frames; i++) {
if (arr[i] == x) {
secondChance[i] = true;
return true;
}
}
return false;
}
static int replaceAndUpdate(int x, int[] arr, boolean[] secondChance, int frames, int pointer){
while (true) {
if (!secondChance[pointer]) {
arr[pointer] = x;
return (pointer + 1) % frames;
}
secondChance[pointer] = false;
pointer = (pointer + 1) % frames;
}
}
static void printHitsAndFaults(String referenceString, int frames) {
int pointer = 0, i, l, x, pf = 0;
int[] arr = new int[frames];
Arrays.fill(arr, -1);
boolean[] secondChance = new boolean[frames];
String[] str = referenceString.split(" ");
l = str.length;
for (i = 0; i < l; i++) {
x = Integer.parseInt(str[i]);
if (!findAndUpdate(x, arr, secondChance, frames)) {
pointer = replaceAndUpdate(x, arr, secondChance, frames, pointer);
pf++;
}
}
System.out.println("Total page faults were " + pf);
}
public static void main(String[] args) {
String referenceString = "0 4 1 4 2 4 3 4 2 4 0 4 1 4 2 4 3 4";
int frames = 3;
printHitsAndFaults(referenceString, frames);
referenceString = "2 5 10 1 2 2 6 9 1 2 10 2 6 1 2 1 6 9 5 1";
frames = 4;
printHitsAndFaults(referenceString, frames);
}
}
def find_and_update(x, arr, second_chance, frames):
for i in range(frames):
if arr[i] == x:
second_chance[i] = True
return True
return False
def replace_and_update(x, arr, second_chance, frames, pointer):
while True:
if not second_chance[pointer]:
arr[pointer] = x
return (pointer + 1) % frames
second_chance[pointer] = False
pointer = (pointer + 1) % frames
def print_hits_and_faults(reference_string, frames):
pointer = 0
pf = 0
arr = [-1] * frames
second_chance = [False] * frames
str_list = reference_string.split()
l = len(str_list)
for i in range(l):
x = int(str_list[i])
if not find_and_update(x, arr, second_chance, frames):
pointer = replace_and_update(x, arr, second_chance, frames, pointer)
pf += 1
print(f'Total page faults were {pf}')
# Driver code
reference_string = '0 4 1 4 2 4 3 4 2 4 0 4 1 4 2 4 3 4'
frames = 3
print_hits_and_faults(reference_string, frames)
reference_string = '2 5 10 1 2 2 6 9 1 2 10 2 6 1 2 1 6 9 5 1'
frames = 4
print_hits_and_faults(reference_string, frames)
function findAndUpdate(x, arr, secondChance, frames) {
for (let i = 0; i < frames; i++) {
if (arr[i] === x) {
secondChance[i] = true;
return true;
}
}
return false;
}
function replaceAndUpdate(x, arr, secondChance, frames, pointer) {
while (true) {
if (!secondChance[pointer]) {
arr[pointer] = x;
return (pointer + 1) % frames;
}
secondChance[pointer] = false;
pointer = (pointer + 1) % frames;
}
}
function printHitsAndFaults(referenceString, frames) {
let pointer = 0, i, l, x, pf = 0;
let arr = new Array(frames).fill(-1);
let secondChance = new Array(frames).fill(false);
let str = referenceString.split(' ');
l = str.length;
for (i = 0; i < l; i++) {
x = parseInt(str[i]);
if (!findAndUpdate(x, arr, secondChance, frames)) {
pointer = replaceAndUpdate(x, arr, secondChance, frames, pointer);
pf++;
}
}
console.log(`Total page faults were ${pf}`);
}
// Driver code
let referenceString = '0 4 1 4 2 4 3 4 2 4 0 4 1 4 2 4 3 4';
let frames = 3;
printHitsAndFaults(referenceString, frames);
referenceString = '2 5 10 1 2 2 6 9 1 2 10 2 6 1 2 1 6 9 5 1';
frames = 4;
printHitsAndFaults(referenceString, frames);
Output:
Total page faults were 9
Total page faults were 11