一尘不染

Java中的内存使用量突发

java

我正在尝试处理Java中正确的内存使用和垃圾回收。无论如何,我都不是新手程序员,但是在我看来,一旦Java接触到一些内存,它就永远不会被释放供其他应用程序使用。在这种情况下,您必须确保
峰值内存 永远不会太高,否则应用程序将继续使用峰值内存使用率。

我编写了一个小示例程序试图证明这一点。它基本上有4个按钮…

  1. BigList = new ArrayList<string>()用大约25,000,000个长字符串项目填充类范围变量。
  2. 呼叫 BigList.clear()
  3. 重新BigList = new ArrayList<string>()分配列表- 再次(以缩小列表大小)
  4. 致电System.gc()-是的,我知道这并不意味着GC会真正运行,但这就是我们所拥有的。

因此,接下来,我在Windows,Linux和Mac OS上进行了一些测试,同时使用默认任务监视器检查报告的内存使用情况的进程。这是我发现的…

  • 窗户 -抽水列表,通话清晰,然后在所有调用GC几次不会减少内存使用情况。但是,使用new几次重新分配列表,然后多次调用GC会将内存使用量降低到起始级别。海事组织,这是可以接受的。
  • Linux (我将Mint 11发行版与Sun JVM一起使用)-与Windows相同。
  • Mac OS- 我执行了与上述相同的步骤,但是即使重新初始化对GC的列表调用似乎也没有效果。该程序将使用数百MB的RAM,即使我的内存不足。

谁能向我解释一下?
有人告诉我一些有关“堆”内存的信息,但我仍然不完全了解它,因此我不确定它是否适用于此。从我所听到的信息来看,无论如何我都不会看到我在Windows和Linux上的行为。

这仅仅是Mac OS的Activity Monitor测量内存使用方式的不同还是发生了其他情况?我希望程序不会因大量的RAM使用而闲置。感谢您的见解。


阅读 326

收藏
2020-12-03

共1个答案

一尘不染

Sun / Oracle
JVM不会将不需要的内存返回给系统。如果您给它提供最大的最大堆大小,并且实际上在某个时候使用了该堆空间,那么JVM不会将其退还给操作系统以用于其他用途。其他JVM会做到这一点(JRockit曾经这样做,但我认为它不再这样做了)。

因此,对于Oracle
JVM,您需要调整应用程序和系统的使用高峰期,这就是它的工作原理。如果您正在使用的内存可以通过字节数组进行管理(例如处理图像等),则可以使用映射的字节缓冲区而不是Java字节数组。映射的字节缓冲区直接从系统获取,不属于堆。当您释放这些对象时(我相信,但不能确定它们是GC的),内存将返回给系统。假设它甚至完全适用,您可能必须使用它。

2020-12-03