`
hacksin
  • 浏览: 10480 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

WeakHashMap应用实例之SNMP4j中缓存的应用

    博客分类:
  • Java
阅读更多

WeakHashMap包路径java.util.WeakHashMap,基于HashMap实现原理同时在保存键时引入了WeakReference(弱引用),这样可以达到引用但不影响gc回收此引用实例的目的,其可以尽量避免内存泄漏的情况出现。这里的弱引用简单解释下,相对于我们平时开发中用的引用关系(即强引用),弱引用不会影响gc对垃圾实例的判断,也就是弱引用中的实例如果不存在强引用是可以被gc的,但被gc回收的时机是不确定的,其依赖gc的运行。

应用场景举例:

如果一个实例键值已经存在强引用,同时我们也需要利用此键值建立其他的映射关系,当此键值无用时(即强引用消失后,那么后来建立的映射关系也就失效了。此时我们可以将映射关系中对此键值的应用设定为弱引用。

 

我在进行SNMP4j协议栈测试时发现其MPv3类中的缓存类Cache就是使用了WeakHashMap实现的代码如下:

protected static class Cache {

    private Map<PduHandle, StateReference> entries = new WeakHashMap<PduHandle, StateReference>(25);

    /**
     * Adds a <code>StateReference</code> to the cache.
     * The <code>PduHandle</code> of the supplied entry will be set to
     * <code>null</code> while the entry is part of the cache, because the
     * cache uses a <code>WeakHashMap</code> internally which uses the
     * <code>PduHandle</code> as key. When
     * @param entry
     *    the state reference to add.
     * @return
     *    {@link SnmpConstants#SNMP_MP_DOUBLED_MESSAGE} if the entry already
     *    exists and {@link SnmpConstants#SNMP_MP_OK} on success.
     */
    public synchronized int addEntry(StateReference entry) {
      if (logger.isDebugEnabled()) {
        logger.debug("Adding cache entry: "+entry);
      }
      StateReference existing =
              entries.get(entry.getPduHandle());
      if (existing != null) {
        if (existing.equals(entry)) {
          if (logger.isDebugEnabled()) {
            logger.debug("Doubled message: "+entry);
          }
          return SnmpConstants.SNMP_MP_DOUBLED_MESSAGE;
        }
        else if (existing.equalsExceptMsgID(entry)) {
          entry.addMessageIDs(existing.getMessageIDs());
        }
      }
      // add it
      PduHandle key = entry.getPduHandle();
      // because we are using a weak has map for the cache, we need to null out
      // our key from the entry.
      entry.setPduHandle(null);
      entries.put(key, entry);
      return SnmpConstants.SNMP_MP_OK;
    }

    /**
     * Delete the cache entry with the supplied <code>PduHandle</code>.
     * @param pduHandle
     *    a pduHandle.
     * @return
     *    <code>true</code> if an entry has been deleted, <code>false</code>
     *    otherwise.
     */
    public synchronized boolean deleteEntry(PduHandle pduHandle) {
      StateReference e = entries.remove(pduHandle);
      return (e != null);
    }

    /**
     * Pop the cache entry with the supplied ID from the cache.
     * @param msgID
     *    a message ID.
     * @return
     *    a <code>CacheEntry</code> instance with the given message ID or
     *    <code>null</code> if such an entry cannot be found. If a cache entry
     *   is returned, the same is removed from the cache.
     */
    public synchronized StateReference popEntry(int msgID) {
      for (Iterator<PduHandle> it = entries.keySet().iterator(); it.hasNext(); ) {
        PduHandle key = it.next();
        StateReference e = entries.get(key);
        if ((e != null) && (e.isMatchingMessageID(msgID))) {
          it.remove();
          e.setPduHandle(key);
          if (logger.isDebugEnabled()) {
            logger.debug("Removed cache entry: "+e);
          }
          return e;
        }
      }
      return null;
    }
  }

 

当时我不理解,为什么这里会用弱引用做缓存,难道他不怕缓存被gc影响数据的丢失么?带着此疑问我做了如下实验:

我先令其缓存一个实例,然后我不手动调用gc看看结果,如下图:



 

之后我先将实例存入缓存(用eclipse打断点来实现),然后手动调用gc:



 

此时断点处继续执行从缓存中获取实例:



 

很奇怪 为什么gc没有将弱引用中的实例回收,猜测此实例肯定存在强引用:



 

 我们看到此实例同时被HashTable引用,因HashTable在一次SNMP操作过程中会一直引用此实例,故其无法gc回收了。

 

总结:

这里不是在给大家讲解SNMP4j是如何进行SNMP操作的,重点在于给大家介绍弱引用的一个应用场景,上面代码中的Cache类完全可以被我们重用到自己的代码中去。但要记住一点就如其名字弱引用一样,我们用这样的缓存一定要当心gc回收。

  • 大小: 33 KB
  • 大小: 34.6 KB
  • 大小: 16.3 KB
  • 大小: 39.4 KB
  • 大小: 44.6 KB
分享到:
评论

相关推荐

    Java编程WeakHashMap实例解析

    在Java编程中,WeakHashMap的应用场景非常广泛,例如: 1. 缓存:WeakHashMap可以用来存储缓存的数据,避免内存泄露的问题。 2. 线程安全:WeakHashMap可以用来存储线程共享的数据,避免线程安全的问题。 3. 数据...

    WeakHashMap的使用方法详解

    4. WeakHashMap 的应用实例:Tomcat 中的缓存机制使用了 WeakHashMap,通过将 eden 和 longterm 两个缓存结合使用,实现了高效的缓存机制。 5. WeakHashMap 的优点:WeakHashMap 可以自动地清除无用的缓存对象,...

    Android应用源码之图片异步缓存两层缓存.zip

    本资料"Android应用源码之图片异步缓存两层缓存.zip"提供了一个实现这一功能的示例,其中包含一个名为"ListViewPerformance0.2"的项目,很可能是针对ListView性能优化的一个版本。下面将详细介绍这个项目可能涉及的...

    Android应用源码之douBanList(滚动到底部加载新的,软缓存,懒加载).zip

    在Android应用开发中,"douBanList"项目是一个典型的网络数据加载与缓存机制的实现,主要用于在用户滚动到列表底部时动态加载更多数据,同时采用软缓存策略和懒加载技术,优化用户体验。这个项目的源码可以作为...

    应用源码之douBanList(滚动到底部加载新的,软缓存,懒加载).zip

    本篇将深度剖析一款名为“douBanList”的Android应用源码,它实现了滚动到底部自动加载新数据、软缓存以及懒加载等关键功能,这些都是现代移动应用中不可或缺的设计模式。 首先,滚动到底部加载新数据,通常被称为...

    HASHMAP缓存.txt

    标题“HASHMAP缓存.txt”暗示了文档主要关注的是Java编程语言中HashMap作为缓存机制的应用,而描述中的重复文本可能是误操作,实际上并未提供额外的信息。标签同样重复,进一步确认了主题为HashMap缓存。接下来的...

    Android清除缓存

    `CleanMessageUtil.java` 文件很可能包含一个用于清理Android应用缓存的工具类。现在,我们来详细探讨Android缓存的类型、清理方法以及如何编写这样的清理工具。 1. **缓存类型:** - **内存缓存**:Android应用中...

    Android使用缓存机制实现文件下载及异步请求图片加三级缓存

    在Android开发中,缓存机制是提高应用性能和用户体验的关键技术。本文主要探讨了如何在Android平台上使用缓存机制来实现文件下载以及异步请求图片并加入三级缓存。 首先,我们来理解Android中文件下载的缓存策略。...

    Android高级应用源码-Android 图片缓存、加载器.rar

    - 内存缓存是一种快速访问数据的方式,Android中的内存缓存通常使用`LruCache`或者`WeakHashMap`实现。`LruCache`基于最近最少使用原则(LRU),当缓存满时,会优先移除最近最少使用的图片。 - `WeakHashMap`则...

    Android应用源码之android端用于异步加载图片

    在Android中,可以使用WeakHashMap或LruCache(自Android 3.0引入)作为内存缓存的实现。LruCache通过LRU(Least Recently Used)策略管理缓存,当缓存满时,会删除最近最少使用的图片。 3. **文件缓存**: - 文件...

    Android高级应用源码-下载网络图片 (整合多线程、内存缓存、本地文件缓存~).rar

    源码中可能实现了类似的功能,使用`WeakHashMap`或者`LRUCache`作为内存缓存策略。 4. **本地文件缓存**: - 当内存不足以存储所有图片时,本地文件缓存是必要的。Android提供了`SQLite`数据库、`内部存储`和`外部...

    android缓存网络图片

    在Android开发中,图片缓存是一项非常重要的技术,特别是在处理大量网络图片的应用中。网络图片缓存能够提高用户体验,减少网络请求,节省流量,并减轻服务器压力。本文将深入探讨如何在Android应用中实现图片的网络...

    完整版Java web开发教程PPT课件 Java开发进阶教程 第20章 数据库连接池,缓存(共15页).pptx

    在实际开发中,正确配置和使用数据库连接池和缓存能够显著提升Java Web应用的性能和响应速度。例如,通过调整连接池参数如最小连接数、最大连接数、超时时间等,可以平衡资源利用率和响应速度。而在缓存策略上,需要...

    安卓开发-下载网络图片 (整合多线程、内存缓存、本地文件缓存~) .zip.zip

    本资源“安卓开发-下载网络图片 (整合多线程、内存缓存、本地文件缓存~) .zip.zip”显然提供了一个实现这一功能的实例,包括了多线程下载、内存缓存和本地文件缓存的综合运用。以下将详细讲解这些关键知识点: 1. ...

    java缓存技术深入剖析

    Javaeye创始人分享的这份“java缓存技术深入剖析”旨在帮助开发者更好地理解和应用缓存机制。以下是对该主题的详细阐述: 一、缓存的基本概念 缓存是一种存储技术,用于临时存储常用数据,以减少对主存储器(如硬盘...

    安卓Android源码——douBanList(滚动到底部加载新的,软缓存,懒加载).zip

    这个压缩包文件“安卓Android源码——...总的来说,这个项目提供了学习如何在Android应用中实现滚动加载、缓存和懒加载的实例,对于Android开发者来说,理解并实现这些功能对于提升应用性能和用户体验至关重要。

    android listView图片异步加载(拖动时不加载,双缓存)

    2. 实现内存缓存:使用WeakHashMap或者LruCache作为内存缓存,存储图片的Bitmap对象。 3. 实现磁盘缓存:使用SharedPreferences或文件系统存储图片,可以考虑使用第三方库如DiskLruCache。 4. 图片加载逻辑:在...

    ListView的异步加载图片并缓存

    Android的WeakHashMap或者LruCache可以用来做内存缓存,它们能根据系统内存动态调整缓存大小,防止内存泄漏。 3. **磁盘缓存**:当内存不足以存储所有图片时,可以将图片保存到设备的磁盘上。这通常是在文件系统的...

    AndroiddouBanList(滚动到底部加载新的,软缓存,懒加载).rar

    总的来说,"AndroiddouBanList"项目是一个综合展示了Android应用开发中数据加载、缓存策略和界面优化实践的实例。通过对该项目的学习,开发者可以深入理解如何在实际项目中有效地处理大数据量的列表展示,提高应用的...

    android端用于异步加载图片,内存缓存,文件缓存,图片时淡入淡出动画。-IT计算机-毕业设计.zip

    在Android中,我们可以使用WeakHashMap或者LruCache这类数据结构来实现内存缓存。当内存不足时,系统会自动清理这部分缓存。 文件缓存则是将图片数据保存到设备的外部存储或内部存储中,即使应用关闭,下次启动时仍...

Global site tag (gtag.js) - Google Analytics