暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Java实战-初始化与内存回收

程序员的日记本 2020-08-19
240




为避免浪费你的宝贵时间,请先浏览本文章目录:


1、变量初始化

2、内存回收

2.1、finalize

2.2、GC

3、实战经验-我们是否应该手动GC?

3.1、JDK自动GC

3.2、每创建一次对象GC一次

3.3、每循环100次执行GC一次



01

变量初始化


首先,我们要感谢IDE,因为有了IDE,你不需要关心什么时候该初始化数据,什么时候不用关心初始化数据,因为编译器会提醒你什么时候改初始化,什么时候不该初始化。

static int i;
int kk;
public static void main(String[] args) {
System.out.println(i);
int m;
Date date
System.out.println(m); //提醒你要初始化
System.out.println(date); //提醒你要初始化
}

如果你写出了上面的代码,那么编译器会提醒你,m与date没有被初始化,但是i同样没有初始化,确没有报错提示,就有点匪夷所思了。


还记得我们第一篇文章里面介绍的栈和堆吗?不知道你有没有发现,没有提示要被初始化的数据,都是在对堆里面的数据,编译器提示需要被初始化的数据都是栈上的数据。


其实,并不是堆上的数据不用初始化,而是在对象被创建的时候,JVM帮我做了默认初始化的动作。



02

内存的回收


Java的垃圾自动回收机制,让Java程序员摆脱C和C++手动回收垃圾的痛苦,不过也正是因为如此,也导致很多程序员滥用内存,使得程序运行起来占用内存极高。


finalize

当我们重写finalize方法之后,在对象被GC的时此方法会被调用。

注意,finalize的调用在Java中具有不确定性。由于这些不确定性,不要把很重要的工作放在此方法当中。


gc

手动调用垃圾收集器,释放内存。不过gc本身也要耗费一定内存。

注意,System.gc()的调用在Java中具有不确定性。由于这些不确定性,不要把内存的释放完全寄托在此方法上。

public class Free {
/**
* 执行下面的代码,可能会出现finalize和gc方法根本没有被调用
* 的现象,这就是两个方法的不确定性
*/
public static void main(String[] args) {
int i=0;
User u = new User("zs" , i);
System.gc();
System.out.println(u.age);
}
static class User{
String name;
int age;
public User(String name , int age){
this.name = name;
this.age = age;
}
@Override
protected void finalize() throws Throwable {
System.out.println("当前age=" + this.age+" 被回收");
}
}
}


03

实战经验-我们是否应该手动GC?


实例1:由Java自动执行GC

int i=0;
while(true){
User u = new User("zs" , i);
System.out.println(u.age);
try {
i ++;
u = null;
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}



实例2:每循环一次执行一次GC

int i = 0;
while(true){
User u = new User("zs" , i);
System.out.println(u.age);
try {
i ++;
u = null;
System.gc();
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}


实例3:每循环100次执行一次GC

int i=0;
while(true){
User u = new User("zs" , i);
System.out.println(u.age);
try {
i ++;
u = null;
if(i % 100 == 0)
System.gc();
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}



总结:可以看出每一次都执行一次GC的效果最差,内存一直维持在一个比较高的水平,说明GC的调用已经对程序造成了一定的负担,而通过一定的时间间隔调用一次GC,效果最好,内存占用稳定且一直在一个比较平稳的水平。因此,在实际项目中,还是可以合理的去使用手动GC的。



文中所有代码均可以在线下载

https://gitee.com/wsyjiamian/JavaDiary.git

文章转载自程序员的日记本,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论