我正在Java 5上编写一个客户端Swing应用程序(图形字体设计器).最近,我遇到了java.lang.OutOfMemoryError: Java heap space个错误,因为我对内存使用并不保守.用户可以打开无限数量的文件,程序会将打开的对象保存在内存中.在快速研究之后,我发现有Ergonomics in the 5.0 Java Virtual Machine人和其他人在Windows机器上说JVM默认最大堆大小为64MB.

在这种情况下,我应该如何处理这种限制?

我可以将max heap sizeusingcommand line选项增加到java,但这需要找出可用的RAM并编写一些启动程序或脚本.此外,增加到大约finite个最大值并不能解决这个问题.

我可以重写一些代码,以便经常将对象持久化到文件系统(使用数据库也是一样),从而释放内存.这可能行得通,但可能也有很多工作要做.

如果你能给我指出以上 idea 的细节,或者像automatic virtual memory, extending heap size dynamically这样的替代方案,那就太好了.

推荐答案

最终,无论在哪个平台上运行,您都可以使用有限的最大堆.在Windows 32位系统中,这大约是2GB(不是堆,而是每个进程的内存总量).碰巧Java Select 将默认值变小(可能是为了让程序员无法创建内存分配失控的程序,而不遇到这个问题,并且必须准确地判断它们在做什么).

因此,有几种方法可以决定你需要多少内存,或者减少你正在使用的内存.Java或C#等垃圾收集语言的一个常见错误是保留对正在使用的对象的引用,或者在可能的情况下分配许多对象.只要对象有对它们的引用,它们就会继续使用堆空间,因为垃圾收集器不会删除它们.

在这种情况下,您可以使用Java内存分析器来确定程序中的哪些方法正在分配大量对象,然后确定是否有办法确保它们不再被引用,或者一开始就不分配它们.我过go 使用过的一个选项是"JMP"http://www.khelekore.org/jmp/.

如果您确定分配这些对象是有原因的,并且需要保留引用(取决于您正在执行的操作),那么启动程序时只需要增加最大堆大小.然而,一旦你做了内存分析并了解了你的对象是如何被分配的,你应该对你需要多少内存有更好的了解.

通常,如果您不能保证您的程序将在某个有限的内存中运行(可能取决于输入大小),那么您总是会遇到这个问题.只有在用尽所有这些之后,您才需要考虑将对象缓存到磁盘等.在这一点上,您应该有一个非常好的理由说"我需要Xgb内存",并且您不能通过改进算法或内存分配模式来解决这个问题.通常,只有在大型数据集(如数据库或某些科学分析程序)上操作的算法才会出现这种情况,然后缓存和内存映射IO等技术才会变得有用.

Java相关问答推荐

使用hibiter中特定字段的where条款自定义映射

我们如何直接使用kerminldap服务票证来通过ldap进行身份验证并形成LDAP上下文

编译期间错误(Java 0000)Android .Net MAUI

JPackage-results已安装-如何添加系统属性?

使用ExecutorService时在ThreadFactory中触发自定义newThread函数

我可以在regex中的字符类中放置断言吗?

在Java 8之后,HashMap的最坏情况下时间复杂度仍然是O(n)而不是O(log n)?

填写文本字段后锁定PDF

如何在Java中声明未使用的变量?

Apache POI:使用反射获取zoom 级别

如何修复IndexOutOfBoundsException在ClerView适配器的onRowMoved函数?

RichFaces 3.x-Spring Boot-迁移web.xml

试着做一个2x2的魔方求解算法,我如何找到解路径(DFS)?

为什么使用JDK21获取锁定锁比使用JDK11慢

在Spring Boot应用程序中导致";MediaTypeNotSupportdException&qot;的映像上载

带有Health Check的Spring Boot BuildPack打破了本机映像构建过程

有没有可能在时间范围内得到多种解决方案?

从LineChart<;字符串、字符串和gt;中删除数据时出现特殊的ClassCastException;

我如何为我的Java抵押贷款代码执行加薪操作(&Q)

通过/失败的参数化junit测试方法执行数