我们几乎无法从Java本身改变其回收机制的策列,但我们可以改变我们的编程方式和在编程中的注意事项。
1.Java没有C++中对象析构的功能,但Java的垃圾回收机制是有原则的,它会回收没有变量引用的对象。这种对象没有变量引用它,也就再也不可能有任何方法找到这个“丢失的”对象了——GC回收的就是这种对象。所以当我们确定一个对象不再有任何价值和意义时,将这个对象对应的所有变量引用全部置为NULL,这时这个对象就符合了GC的回收标准。对于我们而言也就相当于手动做了对象析构的操作,至于是否真的回收,那是Java自身的问题,至少和编程人员无关了。
2.当然,对于IO类扫描器、NIO类的套接字等对象,Java还是保留了close()、shutdown() 等方法,当我们不再用这类对象时,一定要调用这些方法关闭对象,也就相当于对象析构和置空。
3.除了人工判断IO,NIO类对象的关闭外,我们还可以使用try(){ }语句(带资源的try语句),将这类对象的创建语句置于资源块中,取义为“尝试打开扫描器或套接字,若成功则进行后边的操作;否则,自动关闭相应的对象”。
4.对于PI=3.14……这样的常量,在使用时,应尽量避免自己创建此类常量对象,尽可能使用Java的Math类中已定义好的的PI、MAX_VALUE、MIN_VALUE 静态常量,可以减少GC的负担——毕竟这类常量总不能被认为是可销毁的吧。
5. 避免在循环中针对同一变量创建对象。说到循环,不得不提一下递归。我们通常认为递归比循环更加耗费内存中的栈区,原因就是因为递归中的变量是以函数为单位产生的,虽然变量同名,但他们储存在内存中不同的单元位置,所以几乎不会出现对象无法被GC回收的现象;但是循环就不一样了,循环操作节省内存的一个很重要的原因就是一个变量依次引用创建的对象,以至于到了循环结束时,多个变量具有相同变量名的变量引用了多个对象,那么明明在循环结束时理想状态下应该只有一个变量名引用一个对象,之前循环中创建的对象都成为GC的回收目标,但是现在所有循环中创建的对象都产生了引用,还具有相同的变量名,以至于手动置空会将所有的对象都置空。反而更加麻烦。
6.使用HashMap、HashSet等泛型集合时,应当尽可能整理数据,削弱集合之间的复杂关系,否则,只要应该被回收的集合与其他集合哪怕只剩一个关系,GC都不会回收这个集合的对象。
原文地址:https://www.cnblogs.com/fusiji/p/11409855.html