Java进程占用越来越多的内存

Java进程占用越来越多的内存,java,linux,memory-management,memory-leaks,process,Java,Linux,Memory Management,Memory Leaks,Process,全部, 我有一个Java内存进程,随着时间的推移,它开始占用越来越多的内存。为了限制堆空间的使用,我将-Xmx选项设置为512M。经过一段时间后,进程内存使用率慢慢达到2GB 我已经使用各种工具(如MAT和YOURKIT)分析了代码中可能存在的内存泄漏,在Java代码中没有发现这种可能的泄漏。代码还使用了一个看起来没有泄漏的本机函数 我有以下问题: 是否可能对Java进程可以使用的总内存造成上限 除了堆之外,JVM的其他内存使用是什么 Linux是否在Windows的“工作集”内存模型上工作,当

全部,

我有一个Java内存进程,随着时间的推移,它开始占用越来越多的内存。为了限制堆空间的使用,我将-Xmx选项设置为512M。经过一段时间后,进程内存使用率慢慢达到2GB

我已经使用各种工具(如MAT和YOURKIT)分析了代码中可能存在的内存泄漏,在Java代码中没有发现这种可能的泄漏。代码还使用了一个看起来没有泄漏的本机函数

我有以下问题:

  • 是否可能对Java进程可以使用的总内存造成上限
  • 除了堆之外,JVM的其他内存使用是什么
  • Linux是否在Windows的“工作集”内存模型上工作,当进程放入后台时,它会释放内存
  • 即使在对512M使用-Xmx选项之后,如果堆使用率增加,JVM也不应该抛出“内存不足”的错误。这使我怀疑内存是由堆空间之外的其他东西泄漏的。从内存转储来看,堆内存似乎没有增加

  • 谢谢你的回答。

    你是如何衡量内存使用率的

    通常有三种内存使用方式:

    • VIRT—虚拟内存大小(KiB) 任务使用的虚拟内存总量。信息技术 包括所有代码、数据和共享库以及 已调出和已映射但未映射的页面 用过
    • RES—驻留内存大小(KiB):任务使用的非交换物理内存
    • SHR—共享内存大小(KiB)It 仅仅反映了 可能与其他进程共享
    虚拟内存大小可能会比您使用-Xmx指定的大(几GB),但这不会造成任何伤害。RES加SHR是您应该看到的

    除了堆之外,还有一类内存使用不受-Xmx(permgen)影响。但这通常限制在几MB。您可能想阅读。

    让我用一个完整的“回复”来补充我的“评论”

    如果您正在进行大量的字符串操作,那么绝对不应该使用“string”类。不管发生了什么,Java有很多很棒的工具(包括但不限于JConsole),可以让您智能地分析问题。你的两个新职位应该是:

    • (有效地操作字符串)和

    • (研究程序的行为;包括堆分配和垃圾回收)

    而且,正如user643011正确指出的那样,还有很多其他可能“泄漏”的东西:包括未关闭的文件、使用大量堆栈空间的大量线程等等

    这里还有一个很好的链接:


    如果您怀疑java应用程序中存在内存泄漏,一定要尝试。它非常好,可以发现它们,并提供非常有用的报告。

    强烈建议:熟悉该工具(或JVM的等效工具),看看它是否能说明发生了什么:您是否对字符串使用了大量操作?修改字符串时,将创建一个新对象(StringBuffer不是真的)。旧的并没有立即被摧毁。jvm会让他呆上一段时间,因为你可能会再次需要它。当前的Java版本会自动生成StringBuilder,以便在幕后为你进行字符串连接。如果可能的话,也更喜欢StringBuilders(未同步)而不是StringBuffers!佩雷洛:是的,我使用了很多字符串,堆中有一堆未收集的字符串。问题是,如果堆大小有上限,为什么进程占用越来越多的内存。为什么它不离开记忆而停止。我强烈地感觉到堆以外的东西正在占用内存。我在这里谈论的是RES内存。另请参见:-大量的线程堆栈,-内存映射文件没有在应该关闭的时候关闭,-一些本机代码库使用堆内存(可能泄漏)。嗨,Paul,我同意你的推理。然而,我的问题是,我没有得到内存不足错误,我的堆空间只有512MB,比实际进程大小小得多。1)我听说问题不是“堆”本身,2)这就是我引用这些特殊链接的原因:它们应该为您提供大量工具和提示,3)特别注意“不关闭/不释放”、“#/threads”和“递归”,并仔细检查引发异常的方法(并仔细检查其堆栈回溯!):