简体   繁体   English

Java堆大小用法

[英]Java heap size usage

I've written a simple application that works with database. 我编写了一个简单的数据库应用程序。 My program have a table to show data from database. 我的程序有一个表来显示数据库中的数据。 When I try to expand frame the program fails with OutOfMemory error, but if i don't try to do this, it works well. 当我尝试扩展框架时,程序因OutOfMemory错误而失败,但是如果我不尝试这样做,它将很好地工作。

I start my program with -Xmx4m parametre. 我使用-Xmx4m参数启动程序。 Does it really need more than 4 megabytes to be in expanded state? 扩展状态是否真的需要超过4 MB?

Another question: if I run the java visualVM I see the saw-edged chart of the heap usage of my program while other programs which is using java VM(such as netbeans) have more rectilinear charts. 另一个问题:如果运行Java visualVM,我会看到程序堆使用情况的锯齿状图表,而其他使用Java VM(例如netbeans)的程序则具有更多的线性图表。 Why is heap usage of my program so unstable even if it does nothing(only waiting for user to push a button)? 为什么即使我什么也不做(仅等待用户按下按钮),程序的堆使用仍然如此不稳定?

Why would you set your maximum heap size to 4 megabytes? 为什么将最大堆大小设置为4 MB? Java is often memory intensive, so setting it at such a ridiculously low level is a recipe for disaster. Java通常会占用大量内存,因此将其设置在如此低的水平是灾难的根源。

It also depends on how many objects are being created and destroyed by your code, and the underlying Swing (I am assuming) components use components to draw the elements, and how these elements are created and destroyed each time a components is redrawn. 它还取决于您的代码正在创建和销毁多少个对象,以及基础的Swing(我假设)组件使用组件来绘制元素,以及每次重绘组件时如何创建和销毁这些元素。 Look at the CellRenderer code and this will show you why objects are being created and destroyed often, and why the garbage collector does such a wonderful job. 查看CellRenderer代码,这将向您展示为什么经常创建和销毁对象,以及为什么垃圾收集器会做得如此出色。

Try playing with the Xmx setting and see how the charts flatten out. 尝试使用Xmx设置,看看图表如何变平。 I would expect Xmx64m or Xmx128m would be suitable (although the amount of data coming out of your database will obviously be an important contributing factor. 我希望Xmx64m或Xmx128m都是合适的(尽管从数据库中出来的数据量显然是一个重要的因素。

You may need more than 4Mb for a GUI with an expanded screen if you are using a double buffer. 如果使用的是双缓冲区,则带有扩展屏幕的GUI可能需要4Mb以上的内存。 This will generate multiple image of the UI. 这将生成UI的多个图像。 It does this to show them quickly on the screen. 这样做是为了在屏幕上快速显示它们。 Usually this is done assuming you have lots and lots of memory. 通常,这是在假设您有很多内存的情况下完成的。

The Sawtooth memory allocation is due to something being done, then garbage collected. 锯齿内存分配是由于完成了某些操作,然后又进行了垃圾回收。 This may be on a repaint operation or other timer. 这可能在重画操作或其他计时器上。 Is there a timer in your code to check some process or value being changed. 您的代码中是否有计时器来检查某些过程或值被更改。 Or have you added code to a object repaint or other process? 还是您已将代码添加到对象重画或其他过程?

You may want to try setting this value to generate a detailed heap dump to show you exactly what is going on. 您可能想要尝试设置此值以生成详细的堆转储,以确切显示正在发生的事情。

-XX:+HeapDumpOnOutOfMemoryError -XX:+ HeapDumpOnOutOfMemoryError

A typical "small" Java desktop application in 2011 is going to run with ~64-128MB. 2011年典型的“小型” Java桌面应用程序将以约64-128MB的速度运行。 Unless you have a really pressing need, I would start by leaving it set to the default (ie no setting). 除非您真的有迫切需要,否则我将首先将其设置为默认值(即无设置)。

If you are trying to do something different (eg run this on an Android device), you are going to need to get very comfortable with profiling (and you should probably post with that tag). 如果您尝试做一些不同的事情(例如,在Android设备上运行),则需要非常熟悉分析(您可能应该使用该标签发布)。

Keep in mind that your 100 record cache (~12 bytes) may (probably) is double that if you are storing character data (Java uses UCS-16 internally). 请记住,如果要存储字符数据(Java内部使用UCS-16),则100条记录缓存(约12个字节)可能是(可能)两倍。

RE: the "unstability", the JVM is going handling memory usage for you, and will perform garbage collection according to whatever algos it chooses (these have changed dramatically over the years). RE:“不稳定”,JVM将为您处理内存使用情况,并将根据其选择的算法(这些年来发生了巨大变化)执行垃圾回收。 The graphing may just be an artifact of the tool and the sample period. 绘图可能只是工具和采样周期的伪影。 The performance in a desktop app is affected by a huge number of factors. 在一个桌面应用程序的性能受到多种因素的数量巨大的影响。

As an example, we once had a huge memory "leak" that only showed up in one automated test but never showed up in normal real world usage. 例如,我们曾经有一个巨大的内存“泄漏”,仅在一项自动测试中出现,而在正常的实际使用中却从未出现过。 Turned out the test left the mouse hovering over a tool tip which included the name of the open file, which in turn had a set of references back to the entire (huge) project. 事实证明,该测试使鼠标悬停在工具提示上,该工具提示包含打开文件的名称,该文件反过来又具有一组引用到整个(巨大)项目的引用。 Wiggling the mouse a few pixels got rid of the tooltip, which meant that the references all cleared up and the garbage collector took out the trash. 将鼠标摆动几个像素即可摆脱工具提示,这意味着所有引用均已清除,垃圾收集器将垃圾取出。

Moral of the story? 故事的道德启示? You need to capture the exact heap dump at time of the out-of-memory and review it very carefully. 您需要在内存不足时捕获确切的堆转储,并非常仔细地检查它。

I think 4mb is too small for anything except a trivial program - for example lots of GUI libraries (Swing included) will need to allocate temporary working space for graphics that alone may exceed that amount. 我认为4mb对于任何琐碎的程序来说都太小了-例如,许多GUI库(包括SWing)将需要为图形单独分配可能超过该数量的临时工作空间。

If you want to avoid out of memory errors but also want to avoid over-allocating memory to the JVM, I'd recommend setting a large maximum heap size and a small initial heap size . 如果要避免出现内存不足错误,又希望避免为JVM过度分配内存,建议您设置一个较大的最大堆大小和一个较小的初始堆大小

  • Xmx (the maximum heap size) should generally be quite large, eg 256mb Xmx(最大堆大小)通常应该很大,例如256mb
  • Xms (the initial heap size) can be much smaller, 4mb should work - though remember that if the application needs more than this there will be a temporary performance hit while it is resized Xms(初始堆大小)可以小得多,应该可以使用4mb-尽管请记住,如果应用程序需要的大小超过此限制,则在调整大小时会暂时影响性能

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

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