Virtual Memory
Problem Description:
This exercise will require you to create a Java program that mimics the operation of an Operating System virtual memory capability. Virtual memory is still used because although the complement of RAM in a modern PC is huge and growing, the size and number of programs that need to be executing simultaneously is growing even faster.
Your program will not attempt to emulate a complete virtual memory capability but rather will demonstrate a two-level memory. The two levels will be implemented as a file on disk and a Java array in memory.
In “real life” the virtual memory capability depends on the ability of the operating system to detect the situation when a program tries to execute an instruction outside its protected area of memory. We will not be executing any code in our virtual memory but will restrict ourselves to data storage.
We will use virtual memory techniques to store an array of 1000 values in the swap file but use an array of only 100 values in RAM to access the entire 1000-element array.
You will create a class definition for a new class, named vMem which will have defined as a class attribute (data member), an actual Java array of 100 8-byte elements of type long (long integer). The class constructor will construct a direct access file large enough to hold 1000 8-byte values (which is 10 times the size of the actual RAM array).
The user (your “main” method for testing) will use the vMem as though it were actually 1000 elements long. But (in the example) the vMem will be actually 100 elements long and will contain only oneof the ten 100-element sections of the larger, conceptual memory. When the user attempts to access data outside of the 100 element array, Java will throw an exception; which you will catch, whereupon the “catch” code will decide which of the stored 100-element pages is needed from the direct-access file. It will find it and replace the data in the 100 element array.
The analogy is that the CPU experiences memory as a huge array of 1-byte elements. It creates a “swap file” where the pieces of a much larger memory are defined. The ram is apportioned to each of the running programs and the apportioning software will allow a program needing 5 megabytes of RAM to exist and execute, using an actual RAM area much smaller. When the in-RAM segment of the program has been used and the CPU attempts to access a part of the larger virtual program, that part is brought into RAM from the swap file on the hard drive.
Your swap-file array will be stored in a direct-access file on the hard drive in its full size (1000 elements). The actual array inside the vMem object will be much smaller, 100 elements. You will use themain test program below, that will test the vMem object by attempting to use the entire 1000 elements that it tried to allocate when the vMem was created. This is done by generating an index value between 0 and (1000-1) and then generating a storage value to be stored at the index and immediately read back from that location. Using the random index will insure that the array accesses will not follow any pattern but will be scattered throughout the entire range of 1000 values.
When the value is immediately read back it is compared with the value that was stored and any discrepancy is noted as an error. Since the storage-retrieval loop executes 1,000,000 times it will use several minutes of elapsed time.
Further testing:
You will add the following functionality to the main program and your exercise will not be considered to be complete until this is complete and error free. You will add a loop which will store a sequence of 1000 descending values in the array. They will then be read and tested to insure that they are still in descending order. Any error will be flagged and the program will be stopped.
—————————————————————————-
import java.util.Random;
public class vMemTest
{
private final static int ARRAYSIZE = 1000;
private final static int VIRTRATIO = 100;
public static void main(String [] args)
{
// make an array of ARRAYSIZE elements
vMem array = new vMem(ARRAYSIZE, ARRAYSIZE/VIRTRATIO);
Random random = new Random();
int index;
long value;
long gotten = 0;
long startTime = System.nanoTime();
for (int j = 0; j < ARRAYSIZE; ++j)
{
for (int i = 0; i < 2; ++i)
{
index = random.nextInt(ARRAYSIZE);
value = random.nextLong();
try
{
array.put(index, value);
gotten = array.get(index);
}
catch(IndexOutOfBoundsException e)
{
long upper = ARRAYSIZE - 1;
System.out.println("The value " + index + " is outside 0.." + upper);
}
// check for error
if ( gotten != value )
{
System.out.println("error at " + i + ", " + j);
return;
}
}
if (j == 0)
{
System.out.print("Working .");
}
else
{
if ((j % 50) == 0)
{
System.out.print(" .");
}
}
}
long endTime = System.nanoTime();
System.out.println("nElapsed time - part 1 (millisec) is " + (endTime - startTime)/1000000);
int j;
startTime = System.nanoTime();
for (int i = 0; i < ARRAYSIZE; ++i)
{
array.put(i, i);
gotten = array.get(i);
if (i != gotten)
{
System.out.println("error01");
}
j = (ARRAYSIZE - 1) - i;
array.put(j, j);
gotten = array.get(j);
if (j != gotten)
{
System.out.println("error02");
}
}
endTime = System.nanoTime();
System.out.println("nElapsed time - part 2 (millisec) is " + (endTime - startTime)/1000000);
int indexValue01 = random.nextInt(ARRAYSIZE);
int prevIndex = indexValue01;
long storeValue01 = random.nextLong();
array.put(indexValue01, storeValue01);
int indexValue02;
while (prevIndex == (indexValue02 = random.nextInt(ARRAYSIZE)));
prevIndex = indexValue02;
long storeValue02 = random.nextLong();
array.put(indexValue02, storeValue02);
startTime = System.nanoTime();
for (int i = 0; i < (ARRAYSIZE); ++i)
{
gotten = array.get(indexValue01);
if (gotten != storeValue01)
{
System.out.println("error03");
}
gotten = array.get(indexValue02);
if (gotten != storeValue02)
{
System.out.println("error04");
}
while (prevIndex == (indexValue01 = random.nextInt(ARRAYSIZE)));
prevIndex = indexValue01;
storeValue01 = random.nextLong();
array.put(indexValue01, storeValue01);
while (prevIndex == (indexValue02 = random.nextInt(ARRAYSIZE)));
prevIndex = indexValue02;
storeValue02 = random.nextLong();
array.put(indexValue02, storeValue02);
}
endTime = System.nanoTime();
System.out.println("nElapsed time - part 3 (millisec) is " + (endTime - startTime)/1000000);
System.out.println("Test complete");
}
}
Expert Answer
Screenshot of the code:
vMemTest.java






vMem.java









Sample Output:

Sample Output2

Code to copy:
vMemTest.java
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Random;
// definition of the vMemTest class.
public class vMemTest {
// define the variables.
private final static int ARRAYSIZE = 1000;
private final static int VIRTRATIO = 100;
// define the main method.
public static void main(String [] args) throws FileNotFoundException, IOException
{
//create an object of class vMem.
vMem array = new vMem(ARRAYSIZE , ARRAYSIZE /VIRTRATIO);
// create randaom object.
Random random = new Random();
// define the variables.
int index;
long value;
long gotten = 0;
long startTime = System.nanoTime();
for (int j = 0; j < ARRAYSIZE ; ++j)
{
for (int i = 0; i < ARRAYSIZE ; ++i) {
index = random.nextInt(ARRAYSIZE );
value = random.nextLong();
// print the value
System.out.println(value);
try{
// call the method put()
array.put(index, value);
// call the method get()
gotten = array.get(index);
}
// if an exception occur catch the IndexOutOfBoundsException.
catch(IndexOutOfBoundsException e)
{
long upperValue = ARRAYSIZE – 1;
System.out.println(“The value ” + index + ” is outside 0..” + upperValue);
}
// check for error
if ( gotten != value )
{
System.out.println(“error at ” + i);
return;
}
}
if (j == 0)
{
System.out.print(“Working .”);
}
else
{
if ((j % 50) == 0)
{
System.out.print(” .”);
}
}
}
// calculate the end time.
long endTime = System.nanoTime();
System.out.println(“nElapsed time – part 1 (millisec) is ” + (endTime – startTime)/1000000);
int j;
// calculate the start time.
startTime = System.nanoTime();
for (int i = 0; i < ARRAYSIZE ; ++i)
{
//call the method put()
array.put(i, i);
// call the method get()
gotten = array.get(i);
if (i != gotten)
{
System.out.println(“error01”);
}
j = (ARRAYSIZE – 1) – i;
//call the method put()
array.put(j, j);
// call the method get()
gotten = array.get(j);
if (j != gotten)
{
System.out.println(“error02”);
}
}
// calculate the end time.
endTime = System.nanoTime();
// print the time.
System.out.println(“nElapsed time – part 2 (millisec) is ” + (endTime – startTime)/1000000);
// declare the varaibles.
int indexValue01 = random.nextInt(ARRAYSIZE );
int prevIndex = indexValue01 ;
long storeValue01 = random.nextLong();
//call the method put()
array.put(indexValue01 , storeValue01);
int indexValue02;
while (prevIndex == (indexValue02 = random.nextInt(ARRAYSIZE )));
prevIndex = indexValue02;
long storeValue02 = random.nextLong();
//call the method put()
array.put(indexValue02, storeValue02);
// calculate the start time.
startTime = System.nanoTime();
for (int i = 0; i < (ARRAYSIZE *ARRAYSIZE ); ++i)
{
gotten = array.get(indexValue01 );
if (gotten != storeValue01)
{
System.out.println(“error03”);
}
//call get() method
gotten = array.get(indexValue02);
if (gotten != storeValue02)
{
System.out.println(“error04”);
}
// check for the condition.
while (prevIndex == (indexValue01 = random.nextInt(ARRAYSIZE )));
prevIndex = indexValue01 ;
// calculate the random values.
storeValue01 = random.nextLong();
array.put(indexValue01 , storeValue01);
while (prevIndex == (indexValue02 = random.nextInt(ARRAYSIZE )));
prevIndex = indexValue02;
storeValue02 = random.nextLong();
// call put() method
array.put(indexValue02, storeValue02);
}
// calculate the end time.
endTime = System.nanoTime();
System.out.println(“nElapsed time – part 3 (millisec) is ” + (endTime – startTime)/1000000);
System.out.println(“Test complete”);
}
}
vMem.java
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
// define the class
public class vMem
{
// define the required varaibles
private static int SIZE;
private static int VIRTRATIO;
private static File location;
private static RandomAccessFile raf;
// define an array of long integer.
private static Long[] array;
final private static long clear = 0;
// define the constructor with the parameters.
public vMem(int arraysize, int length)
throws FileNotFoundException, IOException
{
SIZE = arraysize;
VIRTRATIO = length;
// call the method createMemoryFile()
createMemoryFile();
array = new Long[100];
// call the method clearArray()
clearArray();
}
// definition of the method createMemoryFile()
public static void createMemoryFile()
throws FileNotFoundException, IOException
{
// open the virtualram text file.
location = new File(“./virtualram.txt”);
raf = new RandomAccessFile(location, “rw”);
// a dummy string
String Dummy = “”;
// add 0 to the dummy string.
for (int i = 0; i < 8; ++i)
{
Dummy = Dummy + “0”;
}
for (int i = 0; i < SIZE; ++i)
{
// Fill file with dummy memory
raf.writeUTF(Dummy);
}
}// end of the method createMemoryFile()
// definition of the method put()
public void put(int index, long value) throws IOException
{
// define a variable
int setHundred = 0;
while (true)
{
try
{
// print the index.
System.out.println(index);
// assign the value in the array.
array[index] = value;
// print end.
System.out.println(“end”);
break;
}
// if an exception occur catch the IndexOutOfBoundsException.
catch (IndexOutOfBoundsException e)
{
// write to swap file
// call the method writeToMemory()
writeToMemory(setHundred, array);
// empty the array
clearArray();
// until index less than 100
while (index >= 100)
{
// add 100.
setHundred = setHundred + 100;
//decrease index by 100
index = index – 100;
}
// call the method readFromMemory()
readFromMemory(setHundred, array);
}
}
}// end of the method.
// define the method get()
public long get(int index) throws IOException
{
int setHundred = 0;
long result = 0;
while (true)
{
try
{
// print the index value.
System.out.println(index);
result = array[index];
break;
}
// if an exception occur catch the IndexOutOfBoundsException.
catch (IndexOutOfBoundsException e)
{
// write to swap file
// call the method writeToMemory()
writeToMemory(setHundred, array);
// empty the array
clearArray();
// continue loop until index greater than 100
while (index > 100)
{
// add 100.
setHundred = setHundred + 100;
//decrease index by 100
index = index – 100;
}
// until index greater or equal to 100
while (index >= 100)
{
// add 100.
setHundred = setHundred + 100;
//decrease index by 100
index = index – 100;
}
// call the method readFromMemory()
readFromMemory(setHundred, array);
}
}
// return the value.
return result;
}// end of the method.
// Method to simplify writing to file
private void writeToMemory(int setofhundred, Long[] array) throws IOException
{
// loop to write current array
for (int loop = 0; loop < 100; loop++)
{
raf.seek((10) * (loop + setofhundred));
raf.writeUTF(Integer.toString(loop + setofhundred) + “:”
+ Long.toString(array[loop + setofhundred]));
}
}
private void readFromMemory(int setofhundred, Long[] array) throws IOException
{
// int inttemp = 0;
String temp = “”;
for (int loop = 0; loop < 100; loop++)
{
raf.seek((10) * (loop + setofhundred));
temp = raf.readUTF();
try
{
array[loop] = Long.parseLong(temp.substring(4));
}
catch (NumberFormatException e)
{
System.out.println(“empty”);
}
}
array = array;
}
// define the method clearArray()
private void clearArray()
{
for (int i = 0; i < 100; i++)
{
array[i] = clear;
}
}
}