当前位置: 首页 > 知识库问答 >
问题:

强制清除内存

吴镜
2023-03-14

我的项目遇到了一些内存问题,所以我决定对一些部分进行压力测试,以查看一些性能度量。我正在使用Google的ConcurrentLinkedHashMap库作为LRU内存缓存。我的测试代码的相关部分如下所示:

final ConcurrentLinkedHashMap cache = new ConcurrentLinkedHashMap.Builder<Long,Long>()
            .maximumWeightedCapacity(200000)
            .build();

for (int i = 0; i < 10; i++) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            int count = 0;
            while (count < 1000000) {
                if (throttle) {
                    Thread.sleep(1000);
                    continue;
                }
                cache.put(random.nextLong(), random.nextLong());
                count++;
            }
        }
    }).start();
}

this.wait();

当内存超过50%时,我将throttle(油门)标志设置为true(真)。我有一个监视线程,它每2秒进行一次测量。以下是我得到的数字:

Size: 423902    Weighted Size: 200001   Memory: 0.11229571913729916
Size: 910783    Weighted Size: 200001   Memory: 0.25812696264655144
Size: 1373394   Weighted Size: 200001   Memory: 0.38996117352719034
Size: 2120239   Weighted Size: 200001   Memory: 0.6203725762957892
Size: 2114424   Weighted Size: 200000   Memory: 0.6233790564491212
Size: 2114424   Weighted Size: 200000   Memory: 0.6233790564491212
Size: 2114424   Weighted Size: 200000   Memory: 0.6233790564491212
Size: 2114424   Weighted Size: 200000   Memory: 0.6233790564491212
Size: 2114424   Weighted Size: 200000   Memory: 0.6233790564491212
Size: 2114424   Weighted Size: 200000   Memory: 0.6233790564491212

由于某种原因,我没有看到LRU缓存的被逐出的条目被清理。我听说手动调用系统。gc()是个坏主意。如果是这样,有什么好方法可以有效地清理内存?

另一方面:有人知道ConcurrentLinkedHashMap返回什么吗weightedSize()返回正确的值,但我担心size会返回更大的值。。


共有2个答案

景书
2023-03-14

默认的驱逐策略不是先进先出吗?如果是这样,您是否正在查看第一个插入以查看它们被驱逐?如果您正在查看最后一个,您将看不到它们。

这来自文档:

The default
 * weigher assigns each value a weight of 1 to bound the map by the
 * total number of key-value pairs. A map that holds collections may choose to
 * weigh values by the number of elements in the collection and bound the map
 * by the total number of elements that it contains. A change to a value that
 * modifies its weight requires that an update operation is performed on the
 * map.

因此,根据我的读数,默认情况下加权大小不会改变。

岳出野
2023-03-14

正如您的数字所示,缓存并不严格保证最大值,但会尝试保持高水位线。如果它确实提供了强有力的保证,那么它将通过对每个写操作进行阻塞调用来限制并发性,并且无法有效地维护顶级LRU策略。在Guava的缓存中,我们确实通过使用锁条带来进行限制,但这种权衡是有限制的。

由于CLHM异步连接哈希表和LRU数据结构,这两个数字可能会出现偏差。大小由修饰的ConcurrentHashMap测量。这是在任何给定时刻对键值对的最准确估计。当LRU策略根据其数据结构重播映射操作以确定最近顺序并执行逐出时,将计算加权大小。加权大小保持在预期的最大值,因为当超过阈值时,策略将退出。

预计大小在突发中会有所不同,但缓存始终会尝试快速自我更正。在您的示例中,这种行为会加剧,因为操作系统会为一个大的时间片安排一个线程。这使得它可以执行比真实场景中可能执行的插入更多的插入。摊销的LRU管理意味着逐出无法跟上,因为它在任何给定时刻都会从一个线程中窃取一点时间。为了更好地模拟实际行为,MemoryLeakTest强制在操作之间切换上下文。

如果您实现了逐出侦听器,您应该会看到计数增加,并且已经达到稳定状态。如果强制进行上下文切换,则应该看到大小保持在下限。如果您希望对地图中可能出现的条目总数有更严格的限制,那么最好使用Guava实现。

 类似资料:
  • 问题内容: 有什么办法可以在页面上放置一些代码,以便当有人访问网站时,它会清除浏览器缓存,以便他们可以查看更改? 使用的语言:ASP.NET,VB.NET,当然还有HTML,CSS和jQuery。 问题答案: 如果这是关于和变化,一种方法是到“缓存无效”是通过附加像“ ”为每个版本的文件名。例如: 或者,在文件名之后执行此操作:

  • 问题内容: 这些天,我的应用程序一直在变化,因为我们的团队现在正在运行快速更新。 由于缓存,我们的客户并不总是拥有最新版本的代码。 那么有没有办法强制浏览器清除缓存? 问题答案: 您可以使用一种非常简单的解决方案,其中包括将哈希值附加到脚本文件中。每次部署App时,您都会通过gulp /grunt任务自动为文件提供不同的哈希值。例如,您可以使用gulp-rev。我在所有项目中都使用了这种技术,并且

  • 本文向大家介绍vue项目强制清除页面缓存的例子,包括了vue项目强制清除页面缓存的例子的使用技巧和注意事项,需要的朋友参考一下 异常描述: 支付宝中内嵌h5项目(vue框架开发),前端重新打包上传之后访问页面会导致页面空白、页面tab点击异常之类异常情况,需要手动清除支付宝缓存才可以正常访问。 解决方案: 在HTTP协议中,只有后端返回 expires 或 Cache-Control:max-ag

  • 问题内容: 谁能告诉我Java用什么代码实现清晰屏幕?例如在C ++中 Java使用什么代码实现清晰的画面? 谢谢! 问题答案: 由于这里有几个答案显示了Windows的无效代码,因此请澄清一下: 该命令没有工作,有两个原因: 在Windows的命令行解释器中内置了众所周知的命令,因此没有可通过调用的名为或在标准安装中的可执行文件。 通过启动新进程时Runtime.exec,标准输出将重定向到启动

  • 问题内容: 我正在尝试了解拉出git repo的“擦除仓库并强制克隆”和“在结帐前清洁”这两个选项之间的区别。查看这两个选项的帮助部分,它们似乎都具有相似的功能,我无法分辨出它们的区别。它们的外观如下: 清除存储库并强制克隆: 在构建之前,请删除工作空间的内容,以确保工作空间完全新鲜。 结帐前清洁 通过删除所有未跟踪的文件和目录(包括.gitignore中指定的文件和目录),在每次签出之前清理工作

  • 我改进了代码,以便从垃圾收集器中获得更好的结果。 现在,当我调用时,它确实释放了所有内存。但是,当我在不调用 的情况下观察内存使用情况时,应用程序确实会保留并使用越来越多的内存。 这是否意味着我的改进正在起作用,我的所有引用都是正确的,我可以忽略JVM是如何自己释放内存的。或者,我的代码中是否存在其他问题,这些问题是JVM在不运行垃圾收集器的情况下保留更多内存的原因。