打印到控制台时 System.out.print 消耗太多内存。有没有可能减少?

我有简单的程序:


public class Test {

    public static void main(String[] args) {

        for (int i = 0; i < 1_000_000; i++) {

            System.out.print(1);

        }

    }

}

并启动剖析。结果如下:

http://img2.mukewang.com/6288a75600011a6b05530333.jpg

我假设内存增长是因为这个方法调用:


public void print(int i) {

        write(String.valueOf(i));

    }

有没有办法在没有内存消耗的情况下在控制台中打印int值?


在本地机器上,我尝试增加if (i % 10000 == 0) System.gc();循环和内存消耗。但是检查解决方案的系统不会做出决定。我试图更改步骤的值,但仍然没有通过内存(应该工作小于 20mb)或时间(<1sec)


MM们
浏览 664回答 3
3回答

郎朗坤

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

宝慕林4294392

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

慕田峪4524236

内存使用模式对于 java 来说是典型的。您的代码无关紧要。要控制 java 内存使用,您需要使用一些 -X 参数,例如“-Xms512m -Xmx512m”将最小和最大堆大小设置为 512m。顺便说一句,为了最小化类似母猪的内存图,建议将最小和最大大小设置为相同的值。当您运行 java 时,可以在命令行上将这些参数提供给 java,例如:java&nbsp;-Xms512m&nbsp;-Xmx512m&nbsp;myProgram还有其他方法。这是一个链接,您可以在其中阅读更多信息:Oracle 文档。还有其他参数控制堆栈大小和其他一些东西。如果在没有考虑内存使用情况的情况下编写代码本身,也可能会影响内存使用,但在您的情况下,它的代码太琐碎而无法做任何事情。大多数内存问题都是通过配置 jvm 内存使用参数来解决的
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java