finalize()是当垃圾回收器确定不存在对该对象的更多引用时,对象的垃圾回收器调用该方法。 两段代码最重要的区别在于t = null的位置。 1中代码修改:while (true) { try { Test t = new Test(); Thread.sleep(1); t = null; list.add(t); System.out.println(Runtime.getRuntime().freeMemory()); } }这样和2一样会调用finalize()。 修改前t = null根本没有释放掉Test对象,自然不会调用finalize()。
to c2one :的确是一直在减少,但是过一会还会增多,因为进行了垃圾回收!可是我却没有看到我的finalize()的运行! to jamesfancy : 事实上的确没有溢出,这也是我比较迷糊的地方! JVM在这过程中进行了垃圾回收,但是我却没有看到我的finalize()方法运行!难道它回收的是其它的内存?
to bao110908 :其实我就是在找一个好的办法使List中的对像内存能够被释放!一个好的办法是list用完之后直接清空,然后将list=null但是在三层架构中,我实在无法知道view层何时能够用完我Action中的list对像!迷茫啊!大家说用Action的finalize()方法进行清理工作会不会有什么后遗症呢?
这个不是一直打印内存在减少?
两段代码最重要的区别在于t = null的位置。
1中代码修改:while (true) {
try {
Test t = new Test();
Thread.sleep(1);
t = null;
list.add(t);
System.out.println(Runtime.getRuntime().freeMemory());
}
}这样和2一样会调用finalize()。
修改前t = null根本没有释放掉Test对象,自然不会调用finalize()。
to jamesfancy :
事实上的确没有溢出,这也是我比较迷糊的地方!
JVM在这过程中进行了垃圾回收,但是我却没有看到我的finalize()方法运行!难道它回收的是其它的内存?
jvm会把长期没有使用的对象,放到硬盘里,从而释放了一部分内存上的空间。
代码1中,没有任何对象被释放,只是换了个存储的空间而已。
个人意见。
t=null;
这表示t指向的原来对象没有被释放,因为list已经引用了这个对象JVM中所指的空闲对象是没有被其它非空闲对象引用时,才会释放的。所以上面的t不释放,而且如果你去掉了Thread.sleep(1);会很快就内存溢出。WeakReference<Test> wr = new WeakReference<Test>(t);
list.add(wr);
这样wr是不会被释放的,但是t是可以被释放的(WeakReference的功能)
因为项目中用到了很多的List 所以想利用JAVA的弱引用帮助JVM清理其被占用的内存空间,但是前台用的是freeer,因为现在List中存的是WeakReference,freeer用不了!
所以我想找个其它办法能够帮助JVM清理List所占用的内存空间!还不影响我使用!
是的,但是想依靠手动调用finalize()或者重写finalize()是管理不了内存的,JVM对finalize()的调用全看RP.....其他正如14楼说的....我是这么认为的,既然我们选择使用Java,就不用为内存操心.import java.util.ArrayList;
import java.util.List;public class Test
{
@Override
protected void finalize() throws Throwable
{
super.finalize();
System.out.println("==> 开始回收垃圾啦");
} public static void main(String[] args)
{
// Map map = new HashMap(50);
List<Integer> list = new ArrayList<Integer>(10);
int i = 0;
while (true)
{
try
{
Thread.sleep(100);
for (Integer j = 0; j < 10; j++)
{
list.add(j);
}
list.add(i);
i++;
for (Integer k : list)
{
System.out.println(k);
}
System.out.print("------------------------");
System.out.println(Runtime.getRuntime().freeMemory());
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}JVM貌似在从其他地方释放内存,不过一直执行下去的话,迟早会溢出....
只要程序还在运行,就算我不往list内添加对像了,list内所有对像依然不会被自动回收,除非我将list手工清理一下!但现在我不知道该何时清理list!
Java的内存回收全靠JVM,你手工是不能控制的。当然,适当的把不用的对象引用置为空(释放引用)可以帮忙JVM更快的回收内存。Java中几乎不存在内存泄漏的概念,因为内存都由JVM自己管理了。你千万不要用C++的内存管理的眼光来看Java。Java出现的目的之一就是尽量避免C++中那些复杂的内存操作。要清空List,你可以用list.clear()方法。最后说一句,就算是一个大型的Java应用,也可以不写任何finalize()
根本错误的做法,你只应该将你认为没有用的对象置空,JVM就会自动回收,你不需要理会这个过程
我还是那句话,你根本不应该将所有对象无限制的放入list中!
知道这个东西,没用过
有必要用吗?
to jamesfancy :其实你是看不到Java内存回收的,也许你可以根据内存使用值的变化来判断。但是你又如何知道它到底回收了些什么东西呢?你之所以没看到finalize()方法运行,那是因为那个对象没根本没被回收。如上面很多朋友指出的那样,你在t = null之前使用list.add(t)将t所指的对象引用添加到了一个list当中。这样一来,现在t所指的这个对象就存在两个引用,一个是t,另一个在list中。之后你t = null,释放了一下引用,list中还存在另一个,所以对象是不可能被回收的。你在t = null之后加一句list.clear()试试。事实上的确没有溢出,这也是我比较迷糊的地方!
JVM在这过程中进行了垃圾回收,但是我却没有看到我的finalize()方法运行!难道它回收的是其它的内存?
输出的代码片断:
-----
32
40
104
64==> 开始回收垃圾啦
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
==> 开始回收垃圾啦
==> 开始回收垃圾啦
==> 开始回收垃圾啦
==> 开始回收垃圾啦
==> 开始回收垃圾啦
==> 开始回收垃圾啦
==> 开始回收垃圾啦
==> 开始回收垃圾啦
==> 开始回收垃圾啦
==> 开始回收垃圾啦
==> 开始回收垃圾啦
==> 开始回收垃圾啦...
-----
(2)从Thinking in JAVA中抄出来的:
容器类中有一种特殊的Map:WeakHashMap,它被用来保存WeakReference。它使得“规范映射” (canonicalized mappings)更易于使用。在这种映射中,每个“值”只保存一份实例以节省存储空间。当程序需要那个“值”的时候,便在映射中查询现有的对象,然后使用它(而不是重新再创建)。可将“值”作为“规范映射”的一部分,一同初始化,不过通常是在需要的时候才生成“值”。
这是一种节约存储空间的技术,因为WeakHashMap允许垃圾回收器自动清理“键”和“值”,所以它显得十分便利。对于向WeakHashMap添加“键”和“值”的操作,则没有什么特殊要求。WeakHashMap会自动使用WeakReference包装它们。允许清理元素的触发条件是,不再需要此“键”了
http://topic.csdn.net/u/20080110/19/7cb462f1-cac6-4c28-848e-0a879f4fd642.htmlPS:这株竹子不是紫色的那株...
原则2:不要干涉JVM
Test t = new Test();
//WeakReference<Test> wr = new WeakReference<Test>(t);
//t = null;
//Thread.sleep(1);
//map.put("第"+(i++), wr.get());
list.add(t);
//t=null;
//System.out.println("freeMoney==>"+(Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory()));
System.out.println(Runtime.getRuntime().freeMemory());也就是没有一个垃圾,看看会打印什么,结果是不断的出数字,然后不停的减小,从500多到620多(我是1G的内存,把虚拟内存关了)。最后自然是内存溢出。但是却打印出
==> 开始回收垃圾啦
这个不好理解,这里回收的是什么呢?我大概看了一下,在出现java.lang.OutOfMemoryError之前大概打印了200多行开始回收垃圾啦,那这个垃圾是什么呢?JVM内部的也没这么多吧,难道是强行的把Test给回收了?