项目里遇到垃圾回收问题,大概如下demo,如何保证list每次用完回收


private void test(){
        List<String> list= new ArrayList<String>();
        for ( int i = 0; i < 50000000; i++) {
            String a = new String( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" );
            list.add(a);
        }
        list = null;
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.gc();
    }

试了好多办法都不行,按理说不是全局变量会被回收的,可实际情况是十几天前的对象还占用内存,一直叠加,有没有人遇到过大对象的处理问题!

list.Clear() 试试,我也不确定啊

首先静态变量也是可能被回收的,只是一般情况下不会对静态变量进行回收。
然后末尾的system.gc()并不会强制立即执行gc动作,这里只是告诉gc处理器有意愿进行清理,在大对象用完之后,进行clear就行了
按照你现有贴的逻辑代码,GC是会对list对象中的String对象进行清理的。
1、你这个类是不是多线程实现类,如果是的话,线程任务执行完后,有没有被杀掉。或者有没有引用线程管理池,对执行完任务的线程进行清理。若线程没被清理,构建对象存在一定关联性,可达性算法是不知道需要进行对象清理的。
2、这个类中对于list对象有咩有进行值的指向变更。特别是定义静态变量后,是否给静态变量赋list的值,如果list对象跟静态变量有关联,也可能不会被清理。

可以采用弱引用:一个对象只有弱引用的话,在jvm进行垃圾回收时,对象占用的内存就会被回收,在垃圾回收前,对象还是存在的

Test test3 = (Test) WeakReferenceTest.get();
test3.say();
WeakReferenceTest.clear();//清除引用

首先,循环体中不建议创建对象,比较消耗内存,以你现有的代码为例,每一次循环,你都会创建50000000个字符串对象,没有意义,可以改成如下代码
String str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ;
String a = "";
for ( int i = 0; i < 50000000; i++) {
a = str;
list.add(a);
}
其次,@Scheduled默认是单线程池,效率较低,此处可以自定义声明线程池,并使用线程池进行操作

list.clear()一下试试;如果不想就检查一下这个list有没有被单例对象引用到

list.forEach(a->a=null);
list.clear();
list = null;

加上这一段试试

如有帮助,请采纳,十分感谢!

添加下面这段代码


list.clear();
list.removeAll();
list=null;

其实你这样写就没什么问题了,  没法保证用完就被回收。就算你写了System.gc()也不能保证,
你这样把list设置成空就没啥问题了,况且你还主动调用了System.gc();
我觉得是不是其他的问题造成的,建议从新定位问题, 或者把新生代调大点  


1)首先,java里强烈建议你不要调用System.gc(),调用了也不一定会启动回收,换句话,回收不回收得看我(jvm)的心情
2)如果是大对象,用完要回收的话,直接置其为空,这里就是:list = null,但这也不能保证大对象马上从内存里消失,这也得看jvm的心情
3)所以,java里面,基本不用考虑垃圾回收事宜,现在的jvm已经很聪明,也很勤快!希望能帮到你!

可能原因:

  1. 你的test方法需要开辟很大的内存,而你的新生代放不下,因此直接跑到了老年代,
  2. 后续你的其它GC时没有什么大对象需要存放,触发的Gc完全在年轻代就能搞定,不会触发老年代GC
    后续一直没有触发FullGC,因此在老年代的对象没有被回收,只回收了年轻代的内容

从前边你给出的信息看,很可能不是处理完没释放,而是很多天前就已经产生的任务还没执行,你的定时任务间隔时间是不是小于方法执行所需要的时间了

1、for循环中不要用new关键词
2、for循环次数这么多,耗时多久呀,定时任务一分钟执行一次,都还没来得及清空,定时任务都又执行了
3、不要主动gc,因为你不知道它啥时候进行垃圾回收

考虑一下list.clear();