我找不到内存泄漏的原因。 我使用showMemoryUse()来获取堆栈前后的已用内存。我发现我失去了记忆。 我的代码出了什么问题?有人可以帮帮我吗? 提前谢谢
import java.util.EmptyStackException;
public class Stack {
private Object[] tools;
private int size = 0;
public Stack(int initialCapacity) {
tools= new Object[initialCapacity];
}
public void push(Object object) {
ensureCapacity();
tools[size++] = object;
}
public Object pop() {
if (size == 0){
throw new EmptyStackException();
}
return tools[--size];
}
private void ensureCapacity() {
if(tools.length == size){
Object[] old = tools;
tools = new Object[2 * size + 1];
System.arraycopy(old, 0, tools, 0, size);
}
}
public static void main(String[] args) {
Stack stack = new Stack(10000);
showMemoryUse();
for ( int i = 0; i< 10000; i++){
stack.push("a wallet, wallet, wallet, wallet, string " + i);
}
for ( int i = 0; i< 10000; i++){
System.out.println(stack.pop());
}
showMemoryUse();
}
}
答案 0 :(得分:0)
你应该使用java内存分析器来获取泄漏的对象。
下载后,您需要获取应用程序运行时的heapdump文件。 heapdump将包含正在使用的所有对象和内存累积。
使用内存分析器打开heapdump文件,然后开始在里面导航以查看哪个对象使用的内存最多。然后,您可以从中增强代码以使其无效或关闭某些对象。
答案 1 :(得分:0)
您没有说明如何衡量记忆。
无论如何,简短的故事:你的代码很好,Stack类没有泄漏内存。 main()也没有。
以下更多详情。
在您的示例中,ensureCapacity()永远不会使分配的大小加倍。如果你愿意,你可以放一个&System;会出现一个&#39; System.out&#39;在ensureCapacity()的if()里面,你会看到它从未显示过。这是正常的,因为您使用10000个元素初始化堆栈并放置10000个元素。它们适合,所以不需要增加尺寸。那将是一个使用记忆的地方。 (虽然没有泄露)
我认为,“showMemoryUse()&#39;之间的内存泄漏会让您感觉到什么?调用是字符串对象的创建。
每当你做钱包,钱包,钱包,钱包,字符串&#34; + i,创建一个String对象。
实际上,还有更多。一个名为&#34的String对象;钱包,钱包,钱包,钱包,字符串&#34;创建一次并存储在Java的字符串池中。然后,创建一个StringBuilder并用于连接该字符串和i。然后,StringBuilder的结果存储在一个新的String中。
您可以使用&#39; javap&#39;来查看以上所有信息。工具。
javap -c Stack.class
13: invokestatic #60 // Method showMemoryUse:()V
16: iconst_0
17: istore_3
18: goto 48
21: new #63 // class java/lang/StringBuilder
24: dup
25: ldc #65 // String a wallet, wallet, wallet, wallet, string
27: invokespecial #67 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
30: iload_3
31: invokevirtual #69 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
34: invokevirtual #73 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
37: astore 4
39: aload_2
40: aload 4
42: invokevirtual #77 // Method push:(Ljava/lang/Object;)V
Java已经过优化,即使创建了这些辅助对象也能快速运行,并且它们最终会被垃圾收集。
我想说的是:不要担心。您的代码中没有泄漏。