Java 垃圾收集器和字符串操作

标签 java string garbage-collection

我有一个应用程序执行大量字符串操作,我注意到 jvm 内存使用率非常高,而我什至没有在内存中存储任何内容。

我做了一个示例应用程序来演示这个问题: 我有一个带有一个按钮的简单 JFrame

private void buttonDoWorkActionPerformed(java.awt.event.ActionEvent evt) {
    String randomString = "abc test garbagecollector";

    ArrayList<String> results;

    for(int i=0; i<100000; i++)
        results = doNothing(randomString.split(" "));

    results = null;//No effect
    System.gc();//No effect
}

private static ArrayList<String> doNothing(String[] words) {
    ArrayList<String> results = new ArrayList<String>();

    for (String word : words)
        results.add(word);

    return results;
}

如果您运行此示例,JVM 会占用大约 50Mo 的内存,一旦您按下按钮,它就会增加到 150Mo,并且永远不会下降。 编辑:我指的是 Windows 任务管理器中的“java.exe”进程。

显然,我正在做很多临时字符串副本,但我希望一旦我丢失引用,它们就会被 carbage 收集器释放。

编辑:可能不相关,但我尝试使用 32 位和 64 位版本的 java 1.6。

最佳答案

您需要阐明 的含义,因为您可能会在这里看到许多级别。有些会在 GC 上减少,有些不会。

如果您在 GC 之后查看内存使用情况,您应该看不到增加,如果您看到其他方面有所增加,则可能是最大内存或其他一些数字。

public static long memoryUsed() {
    return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
}

public static void main(String... args) {
    String randomString = "abc test garbagecollector";

    System.gc();
    System.out.printf("Memory used before test started %.1f MB%n", memoryUsed() / 1e6);
    for (int t = 0; t < 5; t++) {
        List<String> results = new ArrayList<String>();

        for (int i = 0; i < 100000; i++) {
            for (String word : randomString.split(" "))
                results.add(word);
        }
        long beforeGC = memoryUsed();
        results = null;
        System.gc();
        System.out.printf("%d: before GC %.1f MB used, after GC %.1f MB used%n",
                t, beforeGC / 1e6, memoryUsed() / 1e6);
    }
}

打印

Memory used before test started 5.7 MB
0: before GC 61.8 MB used, after GC 5.8 MB used
1: before GC 44.3 MB used, after GC 5.8 MB used
2: before GC 44.3 MB used, after GC 5.8 MB used
3: before GC 44.3 MB used, after GC 5.8 MB used
4: before GC 44.3 MB used, after GC 5.8 MB used

关于Java 垃圾收集器和字符串操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13805409/

相关文章:

java - 如何在 Java Play 中删除 HTTP 请求!筛选?

java - JAXB 类实例监听器

c - 函数 my_revstr

java - YUI Compressor Maven 插件在错误的时间执行,而 tomcat 插件未使用 yui-compressor 输出

c++ - 将 char* 绑定(bind)到字符串

c - 如何检查一个字符串的第一个字母与同一字符数组内另一个字符串的最后一个字母

python - 如何保持 Pandas 的内存效率?

java - java中标记为垃圾收集与符合垃圾收集资格

java - 对字符串池对象的弱引用

javascript - 始终在后台运行的桌面应用程序