5

I run a java code that produces a lot of read and write from/to a text file. The program source is very simple and in a loop I write 2000 lines in a test file and then I read them again just to generate a lot of read and write to the disk. But when program is running I monitor the disk by "iostat -d -x 1" I found that there is no change in read in second "r/s" but "w/s" increased as I expected!!! This is a sample output of iostat command:

Device: rrqm/s wrqm/s  r/s   w/s    rsec/s wsec/s   avgrq-sz avgqu-sz await svctm  %util
sda     0.00   913.00  0.00  82.00  0.00   7872.00   96.00    0.58    7.09   7.11  58.30

Device: rrqm/s wrqm/s  r/s   w/s   rsec/s  wsec/s  avgrq-sz  avgqu-sz  await  svctm  %util
sda     0.00   869.00  0.00  79.00  0.00   7584.00    96.00   0.57    7.11   7.18  56.70

Device: rrqm/s wrqm/s  r/s   w/s   rsec/s  wsec/s  avgrq-sz avgqu-sz   await  svctm  %util
sda     0.00   847.00  0.00  77.00  0.00   7392.00   96.00   0.57      7.42   7.43  57.20

Device: rrqm/s wrqm/s  r/s   w/s   rsec/s  wsec/s   avgrq-sz avgqu-sz  await  svctm  %util
sda     0.00  1221.00  0.00  113.00  0.00  10760.00  95.22    0.84     7.47   7.32  82.70

As it is shown, all "r/s" are zero! but in Java program I read as much as I write in the file?! When I run the Java code, number of write per second increases, but there is no change in " r/s" !! Here is java code that I run when monitoring disk :

import java.io.*;

public class Test {

    public static void main(String [] args) throws IOException{

    String fileName = "/scratch/dump_file.txt";
    File f = new File(fileName);
    // Attempt to delete it
    boolean success = f.delete();
    int j=0;
    while(j<20000)
    {
        ++j;
        Writer output = null;
        String text = "A test content";
        File file = new File(fileName);
        output = new BufferedWriter(new FileWriter(file));

        int i=1;
        while(i<2000)
        {
            //Here we start writing 2000 lines into file line by line
            output.write("j==="+Integer.toString(j)+text+Integer.toString(i)+"\n");
            ++i;
        }
        output.close();
        System.out.println("Your file has been written");  

        String line = null;
        try {
            // FileReader reads text files in the default encoding.
            FileReader fileReader = new FileReader(fileName);
            BufferedReader bufferedReader = 
            new BufferedReader(fileReader);
            i=1;
            while((line = bufferedReader.readLine()) != null) {
                //Here we start reading from file line by line and show the result on screen
                ++i;
                System.out.println(line);
            }   
            // Always close file
            bufferedReader.close();         
        }
        catch(FileNotFoundException ex) {
            System.out.println(
                "Unable to open file '" + 
                fileName + "'");                
        }
        catch(IOException ex) {
            System.out.println(
                "Error reading file '" 
                + fileName + "'");                  
            // Or we could just do this: 
            // ex.printStackTrace();
        }
    }
}
}
bdonlan
  • 224,562
  • 31
  • 268
  • 324
Sepehr Samini
  • 963
  • 4
  • 11
  • 15

1 Answers1

6

Most likely, the operating system is caching the file in RAM. Since it's already cached in memory, when you read in Java the OS doesn't need to actually read from the disk - it just gives you the cached copy it has already. This is a lot faster than actually reading from disk; note, however, that as iostat only reports actual disk reads and writes, your cached reads won't show up there.

bdonlan
  • 224,562
  • 31
  • 268
  • 324
  • I don't think so because first I test this by Riak DB for one hour writing and reading from DB but this parameter was zero! I think for a long time, It can't cache all the transactions. – Sepehr Samini Oct 07 '12 at 19:34
  • @SepehrSamini, time doesn't matter, size does. If your DB fits in memory, your reads can be cached for an arbitrarily long time. – bdonlan Oct 07 '12 at 22:07
  • Excellent point @bdonlan, but I'd be surprised if the caching and usage conspired such that no processes read from the disk at all. Perhaps if iostat running 60-second intervals still says r/s = zero then there is an issue reading disk metadata? – Ben Graham Oct 07 '12 at 23:57
  • For OP's benefit, try `free -m`; the 'cached' column shows how much of your memory is given over to disk cache. Mine is currently ~5gb, so @bdonlan is certainly correct that your whole DB could be cached. – Ben Graham Oct 07 '12 at 23:59