如何自动释放5分钟后从内存中释放数据表

时间:2011-03-22 15:43:07

标签: java database caching

我有一个TableHandler,它实现了表加载/重载逻辑。表格是指当用户以表格对象的形式请求数据时从光盘或内存加载的数据。如果新请求到达且表的实例在内存中,那么我只是从内存加载表而不从光盘重新加载它。如果我正在寻找的表不在内存中我只是从光盘加载表。现在随着我的请求越来越多,很多表都被存储在内存中,所以我想在5分钟之后自动从内存中释放一些表,这些表在5分钟内没有被过时。我该如何实现它? 我有像这样的tablehandler类结构

final class TableHandler{

   /*
   Data struct for storing information required for management 
   of the loaded table    instances
   */

    final static class Tableinfo{

       /*
       Table instance.. and other things like table when 
       last modified and whether to referench the table 
       when a next request arrives.
       */

    }

    getTable(){someInternalTableHandler.getTable()}

    replacetable {someInternalTableHandler.replacetable()}

    //Handles loading/reloading logic.

    final static class someInternalTablehandler{

        getTable(){...}
        createTableInstance(){...}
        replaceTable{...}

    } 
}

如何将上述逻辑实现到我的代码中???

4 个答案:

答案 0 :(得分:2)

这听起来就像是内存中的表缓存。看看像EHCache这样的java缓存解决方案,它解决了这个问题等等。

如果您想自己动手,请在Tableinfo类中添加时间戳以存储上次访问时间。然后使用计时器任务作为jzd建议来遍历TableInfo列表,寻找必须“卸载”的那些。

检查here以获取使用Timer和TimerTask的示例

答案 1 :(得分:1)

两个选项:

  1. 如果您的目标是刷新数据,以便重复请求最终看到新数据。然后只需在最后提取数据时向Tableinfo类添加一个Date。如果日期是最近五分钟,则仅使用内存中的副本。
  2. 如果你的目标是减少内存使用并且你有很多表,那么创建一个新的Timer,在5分钟后执行一个从内存中删除表的TimerTask。

答案 2 :(得分:0)

如果我理解正确,java.lang.ref.WeakReferencejava.lang.ref.SoftReference类可能就是你要找的。

仅具有弱引用的行为就像释放了对对象的所有引用一样,允许GC随时清除它。如果GC没有清理你的桌子你仍然可以使用它,如果它已经清理它你需要重新加载它。软引用类似,但是对象通常会保持更长时间并且只有在内存不足时才能最终确定。

如果你想要在5分钟不活动后清除这些东西,你必须使用第三方库或自己做一些事情,没有任何内置类可以提供。

答案 3 :(得分:0)

您可以使用Guava MapMaker执行此操作: http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/MapMaker.html

Map map = new MapMaker().expireAfterWrite(5, TimeUnit.MINUTES).makeMap();

如果您不想对其进行硬编码,则可以在创建的地图中为您的值使用软引用。如果不再引用它们并且JVM的内存不足,这将导致映射的值被删除。

使用弱/软引用滚动自己的地图也不会太难。请查看ReferenceQueueWeakReferenceSoftReference

有些项目允许您使用@Cache注释方法,并且该方法的所有返回值将在不再引用时被缓存和清除。 http://code.google.com/p/tantalizing-eats/