一、问题引入:
java程序员都知道,java有自己的垃圾回收机制,这使得很多java程序员在编程时很少关心内存溢出的问题,很多垃圾的处理都放心大胆的交给java的垃圾回收机制来处理;前段时间做项目时编写一个自动拼接收费站车道图片的组件,有大概100张左右的图片,开始放在一个循环中利用java swing进行图片拼接处理,在进行单元测试的时候发现图片生成到一半的时候抛出了内存溢出异常。
二、问题引发的思考:
1、java不是有垃圾回收机制吗?为什么处理100多张图片就内存溢出了?
2、java何时进行垃圾回收?回收一些什么样的垃圾?
三、问题解决思路:
1、在网上初步查阅相关资料,大部分资料都说到一点,在写程序的时候,当一个对象不使用的时候或使
用完的时候我们就将其手动赋值为null,看到这点,我立即调整自己的代码,将每个图形处理过程中使
用完的对象手动设置为null,期待java垃圾回收机制能自动立即的回收我的垃圾,这样每处理完一张图片,
所创建的对象都应该会被立即回收,内存应该不会再溢出;但结果却是令人失望的,内存没得都任何的处理。
2、想想是不是需要我手动调用垃圾回收呢,于是我立即又更改了代码,再没处理完一张图片后就手动调用垃圾
回收器,结果还是令人失望的。
3、进一步查阅官方资料,资料给出了详细的答案,一个对象被垃圾回收需要满足两个条件:a.该对象不存在其他引用;
b.该对象被使用的线程释放。此时恍然大悟,为啥1、2的尝试都没有成功。罪魁祸首还是在第二点,虽然我即使的
将引用置为null,但是因为所有的图片处理都在一个线程里面,线程拥有这些资源,所以即使手动调用垃圾回收机制,
这些你自己以为是垃圾的东西,java垃圾回收器却不认为是,只有在线程结束的时候线程才会释放这些资源,垃圾回
收器也才能识别这些垃圾,并放心大胆的回收他们。
4、经过3的思考我立即将单线程改为了多线程,每一个图片交由一个单独的线程处理,,每处理完一个图片,线程结束,
垃圾得到及时回收,结果赏心悦目,后台没报任何内存溢出的异常,问题得到解决;
四、问题后的思考:
以前理解的多线程只是为了并发执行任务,提高执行的效率,原来这只是其中一个作用,通过上述问题,你是不是也发现
了另外一个你还不知道的作用----------优化执行内存,防止内存溢出!(完结)