2011-04-05 65 views
1

我写了一个简单的应用程序,可以使用数据库。我的程序有一个表格来显示数据库中的数据。当我尝试扩展框架时,程序失败,出现OutOfMemory错误,但如果我不尝试这样做,则效果不错。Java堆大小的使用

我用-Xmx4m参数开始我的程序。它是否真的需要超过4兆字节处于扩展状态?

另一个问题:如果我运行java visualVM,我会看到我的程序的堆使用情况的锯齿边图表,而其他使用java VM的程序(例如netbeans)具有更直线的图表。为什么我的程序的堆使用如此不稳定(即使它什么都不做)(只等待用户按下按钮)?

回答

1

您可能想要尝试设置此值以生成详细的堆转储,以向您显示发生了什么。

-XX:+ HeapDumpOnOutOfMemoryError

在2011年一个典型的 “小” Java桌面应用程序要与〜64-128MB运行。除非你有非常迫切的需求,否则我会首先将其设置为默认值(即不设置)。

如果你正在尝试做一些不同的事情(例如,在Android设备上运行),你将需要非常熟悉分析(并且你应该使用该标签发布)。

请记住,如果您要存储字符数据(Java在内部使用UCS-16),您的100条记录缓存(〜12个字节)可能(可能)是双倍。

RE:“不稳定”,JVM正在为您处理内存使用情况,并根据它选择的任何算法执行垃圾回收(这些年来这些算法已经发生了巨大变化)。图表可能只是工具和样本周期的人为因素。桌面应用程序的性能受到很多因素的影响。作为一个例子,我们曾经有过一次巨大的内存“泄漏”,只在一次自动化测试中出现,但从未出现在正常的实际使用情况中。原来测试中,鼠标悬停在一个工具提示上,其中包含打开文件的名称,而该文件又有一组引用返回到整个(巨大)项目。摆动鼠标几个像素摆脱了工具提示,这意味着所有的参考清理和垃圾收集器拿出垃圾。

故事的道德?您需要在内存不足时捕获确切的堆转储,并仔细检查它。

1

为什么要将最大堆大小设置为4兆字节? Java通常是内存密集型的,因此将其设置在如此低的水平是一种灾难。

它还取决于您的代码正在创建和销毁多少个对象,并且基础Swing(我假设)组件使用组件绘制元素,以及每次组件如何创建和销毁这些元素重绘。 看看CellRenderer的代码,它会告诉你为什么经常创建和销毁对象,以及为什么垃圾回收器做了这么好的工作。

试着玩Xmx设置,看看图表是如何变平的。我预计Xmx64m或Xmx128m将是合适的(尽管从数据库中传出的数据量显然是一个重要的促成因素。)

+0

我使用100条记录(每条记录约12个字节)从数据库中获取数据,所以它始终使用恒定数量的内存来存储数据库中的数据 – maks 2011-04-05 18:04:55

1

如果您使用的是扩展屏幕,您可能需要超过4Mb的GUI双缓冲区,这将产生多个UI图像,这样做可以在屏幕上快速显示它们,通常这是在假设你有很多很多内存的情况下完成的

锯齿内存分配是由于某些事情完成,然后垃圾回收,这可能在重绘操作或其他计时器上,您的代码中是否有计时器来检查某个进程或值是否发生更改,或者是否已将代码添加到对象重绘或其他进程?

0

我认为4mb对于除了一个简单的程序之外的任何东西都太小了 - 例如很多GUI库(包括Swing)都需要为图形分配临时工作空间,而这些空间可能超过这个数量。

如果你想避免内存不足的错误,但也希望避免过度分配内存给JVM,我建议设置一个大最大堆大小小的初始堆大小

  • Xmx(最大堆大小)应该是 通常是相当大的,例如, 256MB
  • X毫秒(初始堆大小)可以 小得多,4MB应该努力 - 但记住,如果应用程序需要比这更 会出现暂时的性能 命中,同时将被重新调整