【问题标题】:How to allocate heap memory to a java program如何为java程序分配堆内存
【发布时间】:2018-10-22 05:41:00
【问题描述】:

我有一个 java 程序,它在无限 for 循环中创建 20 个不同的字符串对象

 for(int i = 0 ; i >=0 ; i++){
    String s = new String("Test");
    String s1 = new String("Test");
    /*creating more string objects here */
    System.out.println(s);
}

并使用 java -Xms1m -Xmx1m HelloWorld 运行此程序并打开 VisualVM 以监控堆大小。我不确定为什么它在顶部显示大小和最大值均为 2,097,152 B。 不应该是 1,000,000 吗? 而且我也想知道为什么 use 不会增长到 700,000 B 以上。 总是在 300000 到 700000 之间

请看附件,不知道为什么CPU下会出现“此JVM不支持”的消息?

【问题讨论】:

  • 看起来 gc 足够聪明,可以检测到您为循环内的每次迭代创建新实例,因此它们在下一次迭代中符合 gc 条件。如果您更改代码以在循环前创建一个列表,将新字符串添加到循环内的列表中,然后遍历该列表以打印for 循环之外的值,您将看到所有可用内存都将被使用
  • 不支持小至 1MiB 的堆大小; 2MiB 是最小值。除此之外,正如@Ivan 提到的,您的String 实例是临时的,将被垃圾收集。当“伊甸园”空间已满时,这将在次要集合中发生,这是您堆的一小部分。只有仍被引用的对象(称为“幸存者”)可以转移到其他内存区域。

标签: java memory-management memory-leaks garbage-collection


【解决方案1】:

您可以使用几个 JVM 标志:

  • -Xmx 为特定 JVM 设置最大堆内存(像这样使用:-Xmx2G。它将可用堆限制为 2GB)
  • -Xms 为 JVM 设置初始分配的堆数量(使用 ike 这个:-Xms2G。它将初始堆大小设置为 2GB)

您总是可以从现有算法集中设置垃圾收集算法:

  • -XX:+UseG1GC 使用G1 gc
  • -XX:+UseConcMarkSweepGC 使用并发标记和扫描gc

您可以在这里查看一些标志:http://files.zeroturnaround.com/pdf/zt_JVM-options-cheat-sheet.pdf

【讨论】:

  • 谢谢。如何以字节为单位设置堆内存。我正在尝试运行一个简单的 java 程序,它在循环中创建字符串对象,并在达到最大堆大小后抛出内存
  • @question_tech -Xmx100k 将最大堆设置为 100 KB
  • 它不允许我。我收到此错误“VM 初始化过程中发生错误初始堆太小”
  • @question_tech 将最大设置为 128 MB。到达OOM需要更多时间
  • 嗨,Ivan - 我编辑了我的问题。这就是我在 VisualVM 上看到的
猜你喜欢
  • 2022-11-25
  • 2021-11-23
  • 1970-01-01
  • 2019-12-07
  • 2015-05-01
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多