栈上内存
一般定义值类型的数据在栈上存贮,随着定义域消逝,该值类型也就消失了,涉及到
先进后 出的原则;例如:
public class Main {
public static void main(String[] args) {
int a=10;
if(a>10){
int b=2;
}
//当程序运行到注释这一行是,if语句块里的b就被释放了;
}
堆上内存
存贮在对上的数据,一般是引用类型,例如new出来的对象。他们的释放和栈不一样, 不是定义域消逝,就会释放的。是通过java的垃圾回收机制实现的。
即由Java虚拟机(JVM)的垃圾回收器(Garbage Collector, GC)负责的
这个垃圾回收机制并不是时刻清理的,而是等一定时间间隔或者是堆上的内存满了之后,把不被引用的数据清理掉。
因此有一定延迟,具体例子如下:
public class Main {
public static void main(String[] args) {
students a=new students();//定义了一个学生类,new了一个对象出来
students s=null;//定义了一个用来存贮学生类的地址变量
a.setAge(10);
a.paly();
if(a.getAge()>10){
students b=new students();//if语句中的局部学生类实例化。这个b学生数据存贮在堆上
b.setAge(12);
b.paly();
s=b;//把实例化的b学生的地址赋值给s,让s指向b学生在堆上的数据
}
//在这里显然s又引用了b学生在堆上的数据,所以堆上B学生数据就没有被释放
if(s!=null){
s.paly();
}else{
System.out.println("堆上的空间被销毁了,b对象被销毁了");
}
}
//这段程序的结果输出是:
//学生11岁了
//学生13岁了
//学生14岁了
堆数据,我要手动干掉你
总之,堆上的数据是有java的垃圾回收机制来干掉的,不是我手动干掉,我有点不放心。找了一下发现可以通过以下代码,实现手动干掉堆上的数据(由文心一言大模型提供):
try (Resource resource = new Resource()) {
// 使用资源
} catch (Exception e) {
// 处理异常
} // 在这里,resource将自动被关闭,即使发生异常也是如此
好的,接下来测试一下
public class Main {
public static void main(String[] args) {
students a=new students();
students s=null;
a.setAge(10);
a.paly();
if(a.getAge()>10){
try (students b=new students();) {//好的这里报错,提示我们他需要一个autocloseable的类
b.setAge(12);
b.paly();
s=b;
} catch (Exception e) {
// 处理异常
} // 在这里,resource将自动被关闭,即使发生异常也是如此
}
students c=new students();
c=s;
if(c!=null){
c.paly();
}else{
System.out.println("堆上的空间被销毁了,b对象被销毁了");
}
}
}
代码报错,在try那里,提示我们需要一个AutoCloseable类。
后续查资料,java是不需要手动释放这个资源的,他的垃圾回收器会管理。
初学小白,勿喷!!!!