我正在尝试运行一个jar文件,它会导致“内存不足”错误。经过一段时间后。我有时会搜索使用硬盘空间作为Java堆,但大多数解决方案建议优化代码或使用像Ehcache'这样的东西。但问题是,我只有jar文件而且我没有编写代码。所以,我的问题是我可以使用某些机制或软件,通过它我可以让Java将硬盘空间用作堆,而无需以任何方式修改jar文件的代码吗?
答案 0 :(得分:1)
我假设您有一个Java类的JAR文件而没有附带源代码。这当然是有问题的,但是了解这些类正在做什么是很重要的,因为如果这些类导致了一些无法克服的内存泄漏(是的,Java确实会以所谓的形式发生内存泄漏)意外的对象保留)然后跟进的努力可能仍然不足。
话虽如此,但应该注意的是,JVM(特别是Oracle JVM)在您希望它用于运行Java应用程序的 heap 内存量方面提供了一些可配置性。唯一最重要的配置参数是-Xmx
,即所谓的"最大堆内存"。指定此参数时,例如-Xmx6g,JVM,在启动,将询问操作系统(JVM运行的那个)以获取大量内存。具体细节有点复杂,但如果启动时内存不足,则JVM启动失败。有一个复杂的算法来确定此堆内存的默认值,但如果您有需求,则应覆盖上面的默认值。在上面的例子中,你的JVM(java -Xmx6g -jar test.jar
)要求开始使用6 GB的堆。
确定JVM在其生命周期内所需的堆内存的正确值是一种艺术,尽管您可以考虑几件事。最重要的是了解应用程序的运行时特征。您应该知道如何以及何时分配和释放对象(以便垃圾收集器启动),以便在JVM发出下一个分配请求时不会耗尽堆空间。操作系统。在我看来,这就是你的情况 - 在某个地方,正在构建一堆对象,需要操作系统没有的内存。
显然,操作系统会尝试查看是否有大量物理RAM可用,如果可用,则会授予JVM的请求。这是快乐的道路。
然而,这条快乐的道路并不总是因为没有足够的RAM可用。即使这样,操作系统也可以通过名为虚拟内存的操作系统概念来授予请求。没有太多细节(你可以阅读虚拟内存),只需要说OS有一种机制可以通过页面交换机制将硬盘空间用作RAM。换句话说,它可以将数据交换到物理RAM或以对其上运行的所有进程透明的方式将数据交换到硬盘(包括JVM,这只是一个名为java
的进程)
这是您的系统管理员技能可以帮助您的地方。有一些方法可以增加操作系统的交换空间。例如,在Linux上,您可以使用swapon命令来执行此操作。这总会导致一种称为 thrashing 的现象,但这是你能做的最好的事情(你也可以摆脱其他程序以节省内存)。
同样,这可能只会让你到目前为止。如果你的程序中存在内存泄漏,那么没有任何数量的GC(回收未使用的内存,JVM的一个很好的特性)或交换空间可能会帮助你,迟早你会得到可怕的{{1 }}
您应该考虑指定-XX:HeapDumpOnOutOfMemoryError以查看JVM在发生此错误时正在执行的操作。
答案 1 :(得分:0)
您无法使用硬盘空间来运行java程序,
你可以做两件事:
使用以下命令增加堆内存
java -Xmx1024m -jar Test.jar
使用Java8,它使用使用本机内存的元空间 https://dzone.com/articles/java-8-permgen-metaspace