Java中的突发内存使用情况 [英] Burst memory usage in Java

查看:84
本文介绍了Java中的突发内存使用情况的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在Java中获得正确的内存使用和垃圾回收。我不是任何新手程序员,但在我看来,一旦Java触及某些内存,它就永远不会被其他应用程序使用。在这种情况下,您必须确保您的峰值内存永远不会太高,否则您的应用程序将持续使用任何内存使用峰值。



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


  1. 填充类范围变量 BigList = new ArrayList< string> / code>,其中包含大约25,000,000个长字符串项目。

  2. 再次分配列表 - BigList = new ArrayList< string>()(缩小列表大小)
  3. 调用 System.gc() - 是的,我知道这并不意味着GC会真正运行,但它是我们的。

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




  • Windows - 抽取清单,调用clear,然后调用GC几次都不会减少内存使用量。但是,使用 new 重新分配列表,然后多次调用GC会将内存使用量减少回初始级别。 IMO,这是可以接受的。

  • Linux (我在Sun JVM中使用Mint 11发行版) - 与Windows相同的结果。
  • Mac OS - 我遵循上述相同的步骤,但即使重新初始化GC列表调用似乎也没有效果。该程序将使用数百MB的RAM,即使我在内存中没有任何内容。



任何人都可以向我解释这一点?有些人告诉我一些关于堆内存的东西,但我仍然不完全理解它,我不确定它适用于此。从我听说的情况来看,我不应该看到我在Windows和Linux上的行为。



这只是Mac OS的Activity监视器测量内存使用情况还是有其他事情发生?我宁愿不让我的程序闲置大量的RAM使用。感谢您的洞察。

解决方案

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

所以,对于Oracles JVM,您需要调整您的应用程序和您的应用程序系统的高峰使用,这就是它的工作原理。如果您正在使用的内存可以使用字节数组(例如使用图像或其他)进行管理,那么您可以使用映射字节缓冲区而不是Java字节数组。映射的字节缓冲区直接从系统中获取,而不是堆的一部分。当你释放这些对象(并且它们是GC'd,我相信但不确定)时,内存将返回到系统。假设它甚至可以应用,你可能必须玩那个。


I am trying to get a handle on proper memory usage and garbage collection in Java. I'm not a novice programmer by any means, but it always seems to me that once Java touches some memory, it will never be released for other applications to use. In that case, you have to make sure your peak memory is never too high, or your application will continually use whatever the peak memory usage was.

I wrote a small sample program trying to demonstrate this. It basically has 4 buttons...

  1. Fill class scope variable BigList = new ArrayList<string>() with about 25,000,000 long string items.
  2. Call BigList.clear()
  3. Reallocate the list - BigList = new ArrayList<string>() again (to shrink the list size)
  4. A call to System.gc() - Yes, I know this doesn't mean that GC will really run, but it's what we have.

So next I did some testing on Windows, Linux, and Mac OS while using the default task monitors to check on the processes reported memory usage. Here is what I found...

  • Windows - Pumping the list, calling clear, and then calling GC several times will not reduce memory usage at all. However, reallocating the list using new and then calling GC several times will reduce the memory usage back to starting levels. IMO, this is acceptable.
  • Linux (I used Mint 11 distro with Sun JVM) - Same results as Windows.
  • Mac OS - I followed the sames steps as above, but even when reinitializing the list calls to GC seemingly have no effect. The program will sit using hundreds of MB of RAM even though I have nothing in memory.

Can anyone explain this to me? Some people have told me some stuff about "heap" memory, but I still don't fully understand it and I'm not sure it applies here. From what I have heard about it, I shouldn't be seeing the behavior I am on Windows and Linux anyways.

Is this just a difference in the way Mac OS's Activity Monitor measures memory usage or is there something else going on? I would prefer to not have my program idling with tons of RAM usage. Thanks for your insight.

解决方案

The Sun/Oracle JVM does not return unneeded memory to the system. If you give it a large, maximum heap size, and you actually use that heap space at some point, the JVM won't give it back to the OS for other uses. Other JVMs will do that (JRockit used to, but I don't think it does any more).

So, for Oracles JVM you need to tune your app and your system for peak usage, that's just how it works. If the memory that you're using can be managed with byte arrays (such as working with images or something), then you can use mapped byte buffers instead of Java byte arrays. Mapped byte buffers are taken straight from the system, and are not part of the heap. When you free up these objects (AND they are GC'd, I believe, but not sure), the memory will be returned to the system. You'll likely have to play with that one assuming it's even applicable at all.

这篇关于Java中的突发内存使用情况的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆