Saturday 26 July 2014

Using Soft Reference for Caching

Lets take an example

BigObject.java
Used to generate a BigInteger of size 100000000 bits and serialize the data.

SoftCache.java
This file reads all the serialized files generated by BigObject.java. In first case we implement this without using SoftReference.

import java.io.FileNotFoundException;
import java.math.BigInteger;
import java.util.*;
import java.io.Serializable;
import java.io.ObjectOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class BigObject implements Serializable{
    int num;
    BigInteger id;
    Random rand;
    
    BigObject(int num){
        this.num = num;
        rand = new Random();
        id = new BigInteger(100000000, rand);
    }
    
    @Override
    public String toString(){
        return "id = " + num;
    }
    
    @Override
    protected void finalize() throws Throwable{
        try {
            System.out.println(num + " finalized");
        } finally {
            super.finalize();
        }
    }
    public static void main(String args[]) throws FileNotFoundException, IOException{
        for(int i=1; i<100; i++){
            FileOutputStream fileOut = new FileOutputStream(i + ".ser");
            try (ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
                out.writeObject(new BigObject(i));
            }
            fileOut = null;
        }
        
    }
}

import java.lang.ref.*;
import java.util.*;
import java.io.*;
        
public class SoftCache {
    public static void main(String args[]) throws Exception{
        HashMap<Integer, BigObject> map = new HashMap<> ();
        BigObject cache;
        ReferenceQueue rQueue = new ReferenceQueue();
        
        for(int i=1; i<100; i++){
            System.out.print(i +" ");
            try (FileInputStream fileIn = new FileInputStream(i + ".ser");
                 ObjectInputStream in = new ObjectInputStream(fileIn);) {
                cache = (BigObject) in.readObject();
                map.put(i, cache);
                in.close();
            }            
            /* Removes a key, if the value is null */
            Iterator<Map.Entry<Integer,BigObject>> iter = map.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry<Integer,BigObject> entry = iter.next();
                if(entry.getValue()== null){
                    iter.remove();
                }
            }
        }
    }
}

Output
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19  at java.math.BigInteger.stripLeadingZeroBytes(BigInteger.java:3988)
 at java.math.BigInteger.readObject(BigInteger.java:4255)
 at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:483)
 at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1017)
 at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1896)
 at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1801)
 at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
 at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1993)
 at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1918)
 at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1801)
 at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
 at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
 at SoftCache.main(SoftCache.java:15)
Java Result: 1

SoftCache.java using Soft reference

import java.lang.ref.*;
import java.util.*;
import java.io.*;
        
public class SoftCache {
    public static void main(String args[]) throws Exception{
        HashMap<Integer, SoftReference<BigObject>> map = new HashMap<> ();
        SoftReference<BigObject> cache;
        ReferenceQueue rQueue = new ReferenceQueue();
        
        for(int i=1; i<100; i++){
            try (FileInputStream fileIn = new FileInputStream(i + ".ser");
                 ObjectInputStream in = new ObjectInputStream(fileIn);) {
                cache = new SoftReference(in.readObject(), rQueue);
                map.put(i, cache);
                in.close();
            }
            catch(Error e){
                i = i-1;
                //continue;
            }
            
            /* Removes a key, if the value is null */
            Iterator<Map.Entry<Integer,SoftReference<BigObject>>> iter = map.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry<Integer,SoftReference<BigObject>> entry = iter.next();
                if(entry.getValue().get() == null){
                    iter.remove();
                }
            }
        }
    }
}

Sample Output
7 finalized
18 finalized
17 finalized
16 finalized
15 finalized
14 finalized
13 finalized
12 finalized
11 finalized
10 finalized
9 finalized
8 finalized
6 finalized
5 finalized
4 finalized
3 finalized
2 finalized
1 finalized
19 finalized
21 finalized
36 finalized
35 finalized
34 finalized
33 finalized
32 finalized
31 finalized
30 finalized
29 finalized
28 finalized
27 finalized
26 finalized
25 finalized
24 finalized
23 finalized
22 finalized
20 finalized
19 finalized
37 finalized
38 finalized
54 finalized
53 finalized
52 finalized
51 finalized
50 finalized
49 finalized
48 finalized
47 finalized
46 finalized
45 finalized
44 finalized
43 finalized
42 finalized
41 finalized
40 finalized
39 finalized
37 finalized
55 finalized
72 finalized
71 finalized
70 finalized
69 finalized
68 finalized
67 finalized
66 finalized
65 finalized
64 finalized
63 finalized
62 finalized
61 finalized
60 finalized
59 finalized
58 finalized
57 finalized
56 finalized
55 finalized
73 finalized
74 finalized
90 finalized
89 finalized
88 finalized
87 finalized
86 finalized
85 finalized
84 finalized
83 finalized
82 finalized
81 finalized
80 finalized
79 finalized
78 finalized
77 finalized
76 finalized
75 finalized
73 finalized
91 finalized







Prevoius                                                 Next                                                 Home

No comments:

Post a Comment