如何跟踪Java应用程序中使用的内存?

如何跟踪Java应用程序中使用的内存?,java,memory,memory-management,Java,Memory,Memory Management,我有一个广泛使用内存的java应用程序。它保持了一个增长非常快的数据结构,并负责最大的内存使用量 为了避免内存不足,我决定将数据结构刷新到存储库(文件或数据库)并对其进行后期处理 我面临的问题包括选择将数据结构刷新到存储库中的时间(当使用的内存“关闭”以达到允许的最大值时)。一种方法是在每次更新时跟踪数据结构的内存使用情况 dataStructure.onUpdate(new CheckMemoryIfReachedMax() { public v

我有一个广泛使用内存的java应用程序。它保持了一个增长非常快的数据结构,并负责最大的内存使用量

为了避免内存不足,我决定将数据结构刷新到存储库(文件或数据库)并对其进行后期处理

我面临的问题包括选择将数据结构刷新到存储库中的时间(当使用的内存“关闭”以达到允许的最大值时)。一种方法是在每次更新时跟踪数据结构的内存使用情况

         dataStructure.onUpdate(new CheckMemoryIfReachedMax() {
               public void onUpdate(long usedMemory) {
                    if (usedMemory == MaxMemory) {
                        datastucture.flushInRepository();
                    }
               } 
         }
这种情况下的主要问题是,更改数据结构以跟踪内存并不容易

另一种可能的解决方案是从JVM获取已使用的内存,并将其与最大内存进行比较

          Runtime runtime = Runtime.getRuntime();
          long freeMemory = runtime.freeMemory();
          if (freeMemory < MaxUsedMemory) {
              datastucture.flushInRepository();
          }
Runtime=Runtime.getRuntime();
long freemory=runtime.freemory();
if(空闲内存
在这种情况下,问题在于内存使用情况只是给出了内存使用量的提示,因为我们无法预测垃圾收集器删除对象的时间。此解决方案将使我更经常地将数据结构刷新到存储库中,因此应用程序性能可能会因此受到影响


在这些情况下是否使用了一般模式?关于哪种解决方案更适合这个问题,您有什么建议吗?

我认为您应该使用第一种方法,因为比较运行时内存取决于许多因素。因此,为了使用第一种方法,并通过您可以使用的对象使用内存

long getObjectSize(Object objectToSize)
从Instrumentation接口获取对象的大致大小


请参阅“JVM使用的内存”没有好的通用定义,最好的选择是自己跟踪结构的大小,对不起

问题是-JVM将内存用于垃圾和实际数据,在实际垃圾收集发生之前,无法区分两者。这是设计的,实际上是一个主要的优化

一个糟糕的解决方法是使用JMX跟踪上次收集期间释放的内存量(这将是短期垃圾的大小)。这有两个缺点:

  • 一旦长期存在的垃圾堆积起来,你就会得到误报
  • 您将依赖于特定的垃圾收集器和垃圾收集器设置(例如,我不知道G1是否可以实现此方案)

也许可以将第二个解决方案扩展为第一个触发GC(
runtime.GC()
),并且仅在不释放大量内存的情况下进行刷新?@doublep-我认为显式调用GC(在类似于生产代码的情况下也是如此)不是一个好主意。请检查