Mic*_*ael 4 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;
}
Run Code Online (Sandbox Code Playgroud)
如果运行此示例,JVM 会占用大约 50Mo 的内存,一旦您按下按钮,它将升至 150Mo,并且永远不会下降。编辑:我指的是Windows任务管理器中的“java.exe”进程。
显然,我做了很多临时字符串副本,但我希望一旦我丢失引用,它们就会被碳水化合物收集器释放。
编辑:也许不相关,但我尝试使用 java 1.6 32 位和 64 位版本。
您需要澄清您的意思,因为it您可能会在这里看到很多级别。有些会在 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);
}
}
Run Code Online (Sandbox Code Playgroud)
印刷
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
601 次 |
| 最近记录: |