3 回答

TA贡献1921条经验 获得超9个赞
您需要将其转换为字符,而无需每次都int
生成一个新字符。String
这可以通过以下几种方式完成:
编写一个自定义的“int to characters”方法,在 a 中转换为 ASCII 字节
byte[]
(参见@AndyTurner 的示例代码)。然后写byte[]
. 并重复。使用,使用自定义的“int to characters”转换器方法直接填充它,并在缓冲区已满时
ByteBuffer
使用 a输出字节。Channel
并重复。
如果操作正确,您应该能够在不产生任何垃圾的情况下输出数字……除了一次性缓冲区。
请注意,这System.out
是一个PrintStream
包装 aBufferedOutputStream
包装 a FileOuputStream
。而且,当您String
使用其中一种方法直接或间接输出 a 时print
,实际上是BufferedWriter
通过PrintStream
. 它很复杂……显然,该print(String)
方法在这种复杂性的某个地方产生了垃圾。
关于您的编辑 1:当您反复打印出一个常量字符串时,您显然仍在产生垃圾。我对此感到惊讶,但我猜它正在发生在BufferedWriter
.
关于您的编辑 2:当您反复从 a 写入时byte[]
,垃圾生成几乎消失了。这证实了我的至少一项建议会奏效。
但是,由于您正在使用外部配置文件监视 JVM,因此您的 JVM 也在运行一个代理,该代理会定期向您的分析器发送更新。该代理很可能会产生少量垃圾。JVM 中可能还有其他垃圾来源;例如,如果您启用了 JVM GC 日志记录。

TA贡献2021条经验 获得超8个赞
由于您发现打印 abyte[]将内存分配保持在所需范围内,因此您可以使用以下事实:
分配一个字节数组,其 ASCII 表示的长度为Integer.MIN_VALUE(11 - int 可以是最长的)。然后您可以向后填充数组以转换数字i:
int p = buffer.length;
if (i == Integer.MIN_VALUE) {
buffer[--p] = (byte) ('0' - i % 10);
i /= 10;
}
boolean neg = i < 0;
if (neg) i = -i;
do {
buffer[--p] = (byte) ('0' + i % 10);
i /= 10;
} while (i != 0);
if (neg) buffer[--p] = '-';
然后将其写入您的流:
out.write(buffer, p, buffer.length - p);
您可以重复使用相同的缓冲区来写入任意数量的数字。

TA贡献1875条经验 获得超5个赞
内存使用模式对于 java 来说是典型的。您的代码无关紧要。要控制 java 内存使用,您需要使用一些 -X 参数,例如“-Xms512m -Xmx512m”将最小和最大堆大小设置为 512m。顺便说一句,为了最小化类似母猪的内存图,建议将最小和最大大小设置为相同的值。当您运行 java 时,可以在命令行上将这些参数提供给 java,例如:
java -Xms512m -Xmx512m myProgram
还有其他方法。这是一个链接,您可以在其中阅读更多信息:Oracle 文档。还有其他参数控制堆栈大小和其他一些东西。如果在没有考虑内存使用情况的情况下编写代码本身,也可能会影响内存使用,但在您的情况下,它的代码太琐碎而无法做任何事情。大多数内存问题都是通过配置 jvm 内存使用参数来解决的
添加回答
举报