【问题标题】:how to limit java process RAM usage如何限制java进程RAM的使用
【发布时间】:2018-06-28 05:27:44
【问题描述】:

在堆中,我们可以使用 -Xms -Xmx 来限制 ram 的使用时间。

在jvm的堆外,使用NIO的时候可以使用-XX:MaxDirectMemorySize。

但是在这样的比赛中

public class MappedBufferTest {
    static long length = 1024*1024*512; //
    public static void main(String[] args) throws Exception {
        try (FileChannel fc = new RandomAccessFile("data.txt", "rw").getChannel()) {
            MappedByteBuffer out = fc.map(FileChannel.MapMode.READ_WRITE, 0, length);
            int i = 0;
            for (; i < length/2; i++) {
                out.put((byte) 'x');
            }
            Thread.sleep(30*1000);
            System.out.println("writing");
            for (; i < length; i++) {
                out.put((byte) 'x');
            }
            System.out.println("Finished writing");
            Thread.sleep(60*1000);
            fc.close();
        }
    }

}

带有 jvm 选项

-Xms256m -Xmx256m -XX:MaxDirectMemorySize=128m

运行良好,不会出现oom错误。

-XX:MaxDirectMemorySize 不起作用?

java 1.8 操作系统:centos

【问题讨论】:

  • 不工作是什么意思?错误是什么?
  • MaxDirectMemorySize 限制ByteBuffer.allocateDirect 分配的内存。映射的字节缓冲区不计算在内。由于它们由文件支持,因此它们不必占用 RAM - 操作系统可以在认为必要的任何时候将页面刷新到磁盘。
  • 在操作系统的监视器中。我可以将进程的 ram 增长到 512m。为什么不限制128m。
  • 此选项并非旨在限制 RAM 使用率

标签: java jvm


【解决方案1】:

您可以使用 ulimit 来限制进程可用的虚拟内存量,其中包括映射文件。但是你必须考虑所有 JVM 的需求以避免它被杀死。

如果您只关心常驻内存,您也可以使用 cgroups。

【讨论】:

  • 感谢您的帮助。 cgroups 可以帮助我解决问题。我仍然对 -XX:MaxDirectMemorySize 的使用感到困惑。
  • @jin 这限制了使用Bytes.allocateDirect(n)创建的ByteBuffers
【解决方案2】:

映射文件不使用私有内存。您正在使用操作系统的磁盘缓存。

虽然内存映射文件会增加虚拟内存,但数据会根据需要进行分页,因此即使您映射的文件大于主内存,也不会超出您设置的限制。

注意:文件可能在内存中,因为您最近访问过它。如果某个程序碰巧对其进行了内存映射,这并不意味着该程序使用的内存量与该程序是否运行时所使用的内存量相同。

例如在 Linux 上,您可以在不增加堆或直接内存使用量的情况下映射 100 TB 文件。

【讨论】:

    猜你喜欢
    • 2011-08-21
    • 1970-01-01
    • 2012-08-22
    • 1970-01-01
    • 1970-01-01
    • 2011-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多