在Java中导致内存泄漏的最简单方法
可能重复:在Java中导致内存泄漏的最简单方法,java,memory-leaks,Java,Memory Leaks,可能重复: 导致Java内存泄漏的最简单方法是什么 在类范围内创建对象集合 定期向集合中添加新对象 不要删除对保存集合的类实例的引用 由于始终存在对集合和拥有该集合的对象的实例的引用,垃圾收集器将永远不会清理该内存,从而随着时间的推移导致“泄漏”。使用: public static List<byte[]> list = new ArrayList<byte[]>(); publicstaticlist=newarraylist(); 然后添加(大)阵列而不删除它们
导致Java内存泄漏的最简单方法是什么
public static List<byte[]> list = new ArrayList<byte[]>();
publicstaticlist=newarraylist();
然后添加(大)阵列而不删除它们。在某个时刻,你会毫无疑问地耗尽内存。(您可以对任何对象执行此操作,但对于大而完整的阵列,您可以更快地耗尽内存。)
在Java中,如果取消引用一个对象(它不在范围内),它将被垃圾收集。因此,您必须保留对它的引用才能出现内存问题。下面是一个简单的示例
public class Finalizer {
@Override
protected void finalize() throws Throwable {
while (true) {
Thread.yield();
}
}
public static void main(String[] args) {
while (true) {
for (int i = 0; i < 100000; i++) {
Finalizer f = new Finalizer();
}
System.out.println("" + Runtime.getRuntime().freeMemory() + " bytes free!");
}
}
}
公共类终结器{
@凌驾
受保护的void finalize()抛出可丢弃的{
while(true){
螺纹屈服强度();
}
}
公共静态void main(字符串[]args){
while(true){
对于(int i=0;i<100000;i++){
终结器f=新终结器();
}
System.out.println(“+Runtime.getRuntime().freemory()+”bytes free!”);
}
}
}
从我在投票最多的答案中读到的内容来看,您很可能是在要求类似C的内存泄漏。因为存在垃圾收集,所以不能分配一个对象,丢失它的所有引用,让它仍然占用内存——这将是一个严重的JVM错误
另一方面,您可能会发生线程泄漏-当然,这会导致这种状态,因为您可能会有一些线程在运行时引用了对象,并且可能会丢失线程的引用。您仍然可以通过API获取线程引用-请参见尝试以下简单类:
public class Memory {
private Map<String, List<Object>> dontGarbageMe = new HashMap<String, List<Object>>();
public Memory() {
dontGarbageMe.put("map", new ArrayList<Object>());
}
public void useMemInMB(long size) {
System.out.println("Before=" + getFreeMemInMB() + " MB");
long before = getFreeMemInMB();
while ((before - getFreeMemInMB()) < size) {
dontGarbageMe.get("map").add("aaaaaaaaaaaaaaaaaaaaaa");
}
dontGarbageMe.put("map", null);
System.out.println("After=" + getFreeMemInMB() + " MB");
}
private long getFreeMemInMB() {
return Runtime.getRuntime().freeMemory() / (1024 * 1024);
}
public static void main(String[] args) {
Memory m = new Memory();
m.useMemInMB(15); // put here apropriate huge value
}
}
公共类内存{
私有映射dontGarbageMe=newhashmap();
公共内存(){
put(“map”,新的ArrayList());
}
公共空间useMemInMB(长尺寸){
System.out.println(“Before=“+getFreeMemInMB()+”MB”);
很久以前=getFreeMemInMB();
而((在-getFreeMemInMB()之前)
“在计算机科学中,当计算机程序消耗内存但无法将其释放回操作系统时,就会发生内存泄漏(或在此上下文中的泄漏)。”(维基百科)
简单的答案是:你不能。Java会自动管理内存,并释放您不需要的资源。你无法阻止这一切的发生。它将始终能够释放资源。在使用手动内存管理的程序中,这是不同的。您可以使用malloc()在C中获得一些内存。要释放内存,需要malloc返回的指针并对其调用free()。但是如果您不再拥有指针(被覆盖,或者超过了生命周期),那么很遗憾,您无法释放此内存,因此内存泄漏
到目前为止,所有其他的答案在我的定义中都不是真正的内存泄漏。他们的目标都是用毫无意义的东西快速填满记忆。但在任何时候,您仍然可以取消对所创建对象的引用,从而释放内存→ 没有线索。不过,正如我不得不承认的那样,这非常接近,因为他的解决方案是通过无休止的循环强制垃圾收集器“崩溃”垃圾收集器) 答案很长:您可以通过使用JNI编写Java库来获得内存泄漏,JNI可以进行手动内存管理,从而导致内存泄漏。如果调用此库,Java进程将泄漏内存。或者,JVM中可能存在bug,因此JVM会丢失内存。JVM中可能存在bug,甚至可能存在一些已知的bug,因为垃圾收集并不是那么简单,但它仍然是一个bug。按照设计,这是不可能的。您可能需要一些受此类bug影响的Java代码。很抱歉,我不知道其中一个,在下一个Java版本中,它可能不再是一个bug。除非您:
- 实习串
- 生成类
- 调用的本机代码中存在内存泄漏
- 把你不想要的东西放在遗忘或模糊的地方
- 侦听器,尤其是内部类
- 储藏室
- 构建一个Swing GUI,它可以启动无限数量的模式窗口李>
- 让模态窗口在初始化期间执行以下操作:
StaticGuiHelper.getMainApplicationFrame().GetOneOfButtons().addActionListener(新ActionListener()){ 已执行的公共无效操作(操作事件e){ //什么也不做。。。 } })
public class Scratch {
public static void main(String[] args) throws Exception {
long lastOut = System.currentTimeMillis();
File file = new File("deleteme.txt");
ObjectOutputStream out;
try {
out = new ObjectOutputStream(
new FileOutputStream("deleteme.txt"));
while (true) {
out.writeUnshared(new LittleObject());
if ((System.currentTimeMillis() - lastOut) > 2000) {
lastOut = System.currentTimeMillis();
System.out.println("Size " + file.length());
// out.reset();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class LittleObject implements Serializable {
int x = 0;
}
import java.util.ArrayList;
import java.util.Collection;
import java.util.Stack;
public class Box <E> {
private final Collection<Box<?>> createdBoxes = new ArrayList<Box<?>>();
private final Stack<E> stack = new Stack<E>();
public Box () {
createdBoxes.add(this);
}
public void put (E e) {
stack.push(e);
}
public E get () {
if (stack.isEmpty()) {
return null;
}
return stack.peek();
}
}