我们正在尝试缓存数据库选择的结果(在哈希映射中),因此我们不必多次执行它们。每当我们更改数据库时,为了获得应用程序中的更改,我们添加了刷新列表功能。
现在我们有很多要获取的列表,因此从数据库加载选择列表需要花费太多时间。
所以我对这个问题有一些疑问:
如何查看列表使用的内存量? (我已经使用了我们使用垃圾收集器收集内存并采取差异的方法,但是有很多列表,因此需要花费太多时间)
如何优化刷新列表?
感谢您的帮助。
答案 0 :(得分:2)
如何找到列表使用的内存量
我如何优化刷新列表。
确保您使用的是正确的数据收集类型。 看看here。
另请查看Guava collections。
最后一点,通过建议您不要使用System.gc()
,非常,这可能是您遇到性能问题的原因。 This就是原因。
答案 1 :(得分:2)
首先,虽然不想在性能问题上进行概括,但您所看到的问题不太可能完全取决于内存使用,但如果列表很大,则可能会在刷新时发挥作用。大量对象有资格收集。
要解决与垃圾收集相关的问题,有一些经验法则,但它总是归结为打破剖析器调整垃圾收集器 - 还有更多关于垃圾收集器的问题。
但在此之前,任何数据库的加载都将涉及对结果集的迭代,因此您可以进行的最大优化是减小结果集的大小。有几种方法可以做到这一点:
现在所说的一切,我建议你不要首先编写自己的缓存代码。我说这个的原因是:
答案 2 :(得分:1)
这里有两个问题:发现正在使用的内存量和管理缓存。我不确定这两者是否真的密切相关,尽管它们可能是。
发现一个对象使用多少内存并不是非常困难:一个优秀的文章可供JavaWorld使用“Sizeof for Java”。它逃脱了整个垃圾收集惨败,它有很多洞(它很慢,它不计算对象而是堆 - 这意味着其他对象会影响你可能不想要的结果等等)。
管理初始化缓存的时间是另一个问题。我为一家拥有数据网格作为产品的公司工作,因此我有偏见;请注意。
一个选项根本不是使用缓存,而是使用数据网格。我为GigaSpaces Technologies工作,我觉得我们是最好的;我们可以在启动时从数据库加载数据,并将数据保存在内存中作为分布式事务数据存储(因此您的最大成本是网络访问。)我们有社区版和全功能平台,具体取决于您的需要和预算。 (社区版是免费的。)我们支持各种协议,包括JDBC,JPA,JMS,Memcached,Map API(类似于JCache)和本机API。
其他类似的选项包括Coherence,它本身就是一个数据网格,以及Terracotta DSO,它可以在JVM堆上分发对象图。
您还可以查看缓存项目本身:其中两个包括Ehcache和OSCache。 (再次:偏见。我是开启OpenSymphony的人之一,所以我对OSCache情有独钟。)在你的情况下,会发生的事情不是预加载缓存 - 注意我不知道你的应用程序,所以我猜测可能是错误的 - 但需要缓存。获取数据时,首先检查缓存中的数据,只有当数据不在缓存中时才从数据库中获取数据,并在读取时加载缓存。
当然,您也可以查看memcached,虽然我显然更喜欢我的雇主在这里提供。
答案 3 :(得分:0)
请注意调用
System.gc()
或
Runtime.getRuntime().gc()
除非你真的需要这样做,否则是一个坏主意。您应该让VM决定何时释放对象,除非在分析后发现这是使应用程序在客户端VM上运行得更快的唯一方法。
答案 4 :(得分:0)
我倾向于使用YourKit
来做这类事情。这需要钱,但IMO值得每一分钱(除了作为客户之外没有任何联系)。