简体   繁体   English

我怎么知道我的缓存对象使用了多少 memory?

[英]How i can know how much memory my cached objects are using?

We are trying to cache the results of database selects (in hash map), so we wouldn't have to execute them multiple times.我们正在尝试缓存数据库选择的结果(在 hash 映射中),因此我们不必多次执行它们。 and whenever we are changing data base, so for getting the changes in app we have added refresh list functionality.并且每当我们更改数据库时,为了获取应用程序中的更改,我们添加了刷新列表功能。

Now we have a large no of list to fetch, so it taking too much time to load pick list from the data base.现在我们要获取的列表数量很大,因此从数据库加载选择列表需要花费太多时间。

So I have some question regarding this issue:所以我对这个问题有一些疑问:

  1. How I can find out how much memory the list is using?我怎样才能知道列表使用了多少 memory? (I have used the method where we are using garbage collector for collecting the memory and taking the difference but there are many list and so it is taking too much time) (我使用了我们使用垃圾收集器来收集 memory 并取差的方法,但是列表很多,所以需要太多时间)

  2. How I can optimize the refresh list?如何优化刷新列表?

Thanks for the help.谢谢您的帮助。

how i can find how much memory the list is using我怎样才能找到列表使用了多少 memory

how i can optimize the refresh list.我如何优化刷新列表。

Make sure you're using the correct collection type for your data.确保您使用正确的数据收集类型。 Have a look here .看看这里

Also have a look at the Guava collections .也看看番石榴 collections


One last thing, ignis is very right by advising you not to use System.gc() this might be the very reason you're having performance problems.最后一件事,ignis 建议您不要使用System.gc()非常正确的,这可能就是您遇到性能问题的原因。 This is why. 就是为什么。

First, while not wanting to generalize when it comes to performance problems, the issue you're seeing are unlikely to be purely down to memory use, though if the lists are large this could come into play when they're refreshed and a large number of objects become eligible for collection.首先,虽然不想在性能问题方面一概而论,但您看到的问题不太可能完全归结为 memory 的使用,尽管如果列表很大,这可能会在它们被刷新和大量时发挥作用的对象变得有资格收集。

To solve issues relating to garbage collection there's a few rules of thumb, but it always comes down to breaking out a profiler an tuning the garbage collector - there's more on that here .要解决与垃圾收集有关的问题,有一些经验法则,但它总是归结为打破分析器和调整垃圾收集器 -这里还有更多内容。

But before that any loading of a database is going to involve iteration over a result set, so the biggest optimization you can make will be to reduce the size of the result sets.但在此之前,任何数据库加载都将涉及对结果集的迭代,因此您可以进行的最大优化将是减少结果集的大小。 There's a couple of ways to do that:有几种方法可以做到这一点:

  1. if you using a map, try to use keys that don't require loading and do the load when you get a miss.如果您使用 map,请尝试使用不需要加载的键,并在您错过时进行加载。
  2. once loaded, only refresh the rows that have changed since you last loaded the data, though this obivously doesn't solve the start-up problem.加载后,仅刷新自上次加载数据以来已更改的行,尽管这显然不能解决启动问题。

Now all that said, I would not recommend you write your own caching code in the first place.综上所述,我不建议您首先编写自己的缓存代码。 The reasons I say this are:我这么说的原因是:

  1. all modern RDBMS cache, so providing your queries are performant getting the actual result set should not be a bottleneck.所有现代 RDBMS 缓存,因此如果您的查询是高性能的,获取实际结果集不应该成为瓶颈。
  2. Hibernate provides not only ORM but a robust and well understood caching solution. Hibernate 不仅提供了 ORM,而且提供了一个强大且易于理解的缓存解决方案。
  3. if you really need to cache massive datasets, use Coherence or similar - the cache can be started in a seperate JVM and your application doesn't need to take the load hit.如果您确实需要缓存大量数据集,请使用 Coherence 或类似工具 - 缓存可以在单独的 JVM 中启动,您的应用程序不需要承受负载。

You have two problems here: discovering how much memory is in use, and managing a cache.这里有两个问题:发现有多少 memory 正在使用中,以及管理缓存。 I'm not sure that the two are really closely related, although they may be.我不确定这两者是否真的密切相关,尽管它们可能是。

Discovering how much memory an object uses isn't extremely difficult: one excellent article you can use for reference is " Sizeof for Java " from JavaWorld.发现 memory 和 object 使用了多少并不是非常困难:一篇出色的文章可以作为参考,来自 JavaWorld 的“Java 的 Sizeof ”。 It escapes the whole garbage collection fiasco, which has a ton of holes in it (it's slow, it doesn't count the object but the heap - meaning that other objects factor into your results that you may not want, etc.)它逃避了整个垃圾收集惨败,其中有很多漏洞(它很慢,它不计算 object 而是堆 - 这意味着其他对象会影响你可能不想要的结果等)

Managing the time to initialize the cache is another problem.管理初始化缓存的时间是另一个问题。 I work for a company that has a data grid as a product, and thus I'm biased;我在一家将数据网格作为产品的公司工作,因此我有偏见; be aware.意识到。

One option is not using a cache at all, but using a data grid.一种选择是根本不使用缓存,而是使用数据网格。 I work for GigaSpaces Technologies , and I feel ours is the best;我在GigaSpaces Technologies工作,我觉得我们是最好的; we can load data from a database on startup, and hold your data there as a distributed, transactional data store in memory (so your greatest cost is network access.) We have a community edition as well as full-featured platforms, depending on your need and budget.我们可以在启动时从数据库加载数据,并将您的数据作为分布式事务数据存储保存在 memory 中(因此您最大的成本是网络访问。)我们有一个社区版以及全功能平台,具体取决于您的需求和预算。 (The community edition is free.) We support various protocols, including JDBC, JPA, JMS, Memcached, a Map API (similar to JCache), and a native API. (The community edition is free.) We support various protocols, including JDBC, JPA, JMS, Memcached, a Map API (similar to JCache), and a native API.

Other similar options include Coherence, which is itself a data grid, and Terracotta DSO, which can distribute an object graph on a JVM heap.其他类似的选项包括 Coherence,它本身就是一个数据网格,以及 Terracotta DSO,它可以在 JVM 堆上分布 object 图。

You can also look at the cache projects themselves: Two include Ehcache and OSCache.您还可以查看缓存项目本身:两个包括 Ehcache 和 OSCache。 (Again: bias. I was one of the people who started OpenSymphony, so I've a soft spot for OSCache.) In your case, what would happen is not a preload of cache - note that I don't know your application, so I'm guessing and might be wrong - but a cache on demand. (再次:偏见。我是创建 OpenSymphony 的人之一,所以我对 OSCache 情有独钟。)在您的情况下,会发生的不是缓存的预加载 - 请注意,我不了解您的应用程序,所以我猜测并且可能是错误的 - 但按需缓存。 When you acquire data, you'd check the cache for data first and fetch from the DB only if the data is not in cache, and load the cache on read.获取数据时,首先检查缓存中的数据,仅当数据不在缓存中时才从数据库中获取数据,并在读取时加载缓存。

Of course, you can also look at memcached, although I obviously prefer my employer's offering here.当然,你也可以看看 memcached,虽然我显然更喜欢我的雇主在这里提供的产品。

Be aware that invoking请注意,调用

System.gc()

or或者

Runtime.getRuntime().gc()

is a bad idea unless you really need to do that.除非您真的需要这样做,否则这是一个坏主意。 You should leave the VM the task of deciding when to free objects, unless after profiling you found that it's the only way to make the application go faster on your client's VM.您应该让 VM 决定何时释放对象的任务,除非在分析后发现这是使应用程序 go 在客户端 VM 上更快的唯一方法。

I tend to use YourKit for this sort of thing.我倾向于将YourKit用于此类事情。 It costs money but IMO is worth every penny (no connection other than as a customer).它要花钱,但 IMO 值得每一分钱(除了作为客户之外没有任何联系)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM