繁体   English   中英

设置最大堆大小是否会影响字符串池大小?

[英]Is the string pool size affected by setting max heap size?

我有一个 java 应用程序,它有一个奇怪的 memory 用法,我注意到1.4g消耗显着高于最大堆大小( Xmx使用量为800m

在此之前最近的变化之一是使用中的唯一字符串大幅增加,所以我想我可能在堆外使用了很多 memory 的许多字符串 - 这可能吗?

我正在运行 java 11。

编辑:

例如,在这篇文章中它提到:

当我们使用 new() 操作符创建一个字符串 object 时,它总是在堆 memory 中创建一个新的 object。 另一方面,如果我们使用字符串文字语法(例如“Baeldung”)创建一个 object,它可能会从字符串池中返回一个现有的 object,如果它已经存在的话。

给人以 2 个不同区域的印象 - 堆和字符串池。

在 JDK 中,包含实习字符串的字符串池由两部分组成:

  1. hash 表,该表在堆外分配并包含对实习字符串的引用。 此 memory 区域在 Native Memory 跟踪报告中显示为“字符串表”。
  2. 实习字符串内容。 这些是 Java 堆中的常规java.lang.String对象。

因此,字符串池同时具有堆内和堆外部分。 堆外部分通常更小,但如果应用程序创建了太多的内部字符串,它仍然可能需要大量额外的 memory。

使用Native Memory Tracking来查找 String 表消耗的 memory 的数量。

请参阅此答案以查找该过程可能比-Xmx花费更多 memory 的其他原因。

自 Java 7 以来,字符串池一直是常规堆的一部分(参见此处)。 所以常规堆大小也限制了字符串池的大小。

你应该从那篇文章中得到真正的东西是new String(...)总是创建一个新的String object ,它不同于以前创建的所有String对象。 对于与字符串文字相对应的String object,情况并非如此。

我注意到 memory 的消耗明显高于最大堆大小(Xmx 为 800m,使用量为 1.4g)。

对此的解释是,JVM 使用不属于常规堆的 memory 有多种方式。 这些包括:

  • memory 用于 JVM 可执行文件及其共享库
  • memory 用于应用程序加载的本机代码库
  • memory 段用于 Java 线程堆栈
  • memory 用来表示元空间……它保存着 JIT 编译的本机代码等等,
  • 本机代码分配的“本机”堆中的 memory; 例如使用malloc
  • memory 分配给直接缓冲区

You can use https://visualvm.github.io/index.html to analyse and inspect for example your occupied memory and heap.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM