Java Singleton Memory Leak具体

时间:2016-08-05 19:14:21

标签: java memory-leaks singleton

我的基本程序是读取一个excel文件并将其存储在ConcurrentHashMap缓存中。这个ConcurrentHashMap将String作为键,并且每当修改excel文件时都必须更新一些值Object.ThisConcurrentHashMap以便加载/替换new /此地图中的旧值。

以下是我实现它的方式.ExcelDataFile不是单例,但想法是尽可能少的ExcelDataFile实例,如2或3.Excel文件将每隔15分钟频繁修改。

我的第一个问题是ExcelDataFile'getInstance()方法是否返回单例。

如果它不是单例,我的第二个问题是特定于MemoryLeaks.I我知道这个程序是弱一致的,但它可能导致内存泄漏,因为我没有在getInstance()方法中使用类级别锁。相反我依赖于volatile feilds (origData和excelDataFile(静态引用))。

我知道这永远不会是单例。在创建实例时,这里存在竞争条件。使用修改后的excel文件,即使在具有易失性静态引用和volatile origDate之后,两个线程最终会创建两个实例。当多个实例被创建时,静态ConcurrentHashMap也会导致内存泄漏。我选择了伪单例的这种易失性方式,因为指令不会被重新排序。但我不确定这是否比使用类级锁更好。并且还跳过类级别锁定ConcurrentHashMap(因为它没有意义)

public class ExcelDataFile {




    public static String DATA_FILE_PATH ="/export/data.xlsx";

    private  static final Object CLASS_LOCK = new Object();

    private static volatile long origDate;
    private static volatile ExcelDataFile excelDataFile ;


    private static ConcurrentHashMap<String,Object> dataLocalMap = new ConcurrentHashMap<String,Object>();

    private ExcelDataFile(String dataFile){
        ExcelDataReader reader = new ExcelDataReader(dataLocalMap);
        reader.readExcelFile(dataFile);

    }

    public static ExcelDataFile getInstance(){

        long newDate = getDate(DATA_FILE_PATH);

        //0L if the file does not exist or if an I/O error occurs
        if(newDate ==0){
            dataLocalMap.clear();
        }

            if(excelDataFile == null || (newDate!=origDate)){

                dataLocalMap.clear();

                excelDataFile= new ExcelDataFile(DATA_FILE_PATH);
                origDate = newDate; 

            }

        return excelDataFile;

    }





    protected static long getDate(String fileName) throws SecurityException {
        File file = new File(fileName);
        long lastModifiedDate = file.lastModified();
        return lastModifiedDate;
    }


    public Object getData(String key){
        return dataLocalMap.get(key);
    }


}
public class ExcelDataReader {

private static final String excelSheetName="excelsheet";
private ConcurrentHashMap<String,Object> map = null;

public ExcelDataReader(){

}

public ExcelDataReader(ConcurrentHashMap<String,Object> dataMap){
    map = dataMap;
}



public ConcurrentHashMap<String,Object> readExcelFile(String excelFilePath){

    //read the excel file and  convert the rows into value objects and put them in the ConcurrentHashMap
    Object obj = new Object();
    map.put("TEST",obj);

    return map;  

}



}

将从多个线程调用此getInstance()方法,并使用E xcelDataFile .getData()方法获取缓存数据。

多个线程将使用以下代码

从此ConcurrentHashMap获取数据
public static Object getCacheData(String key){

            ExcelDataFile dataFile = ExcelDataFile.getInstance();
            Object test = null;
            if(null!=dataFile){
                              test  =dataFile.get(key);
                             }

return test;

}

0 个答案:

没有答案