目录:
1.内存分析
2.两种垃圾回收机制和原理
3.对垃圾回收机制的简单理解
1.内存分析:
(1)栈区:
(1)(方法执行的内存模型)也就是说每一个方法执行相关调用都在栈里边,每个方法被调用都会创建一个栈帧(用来储存局部变量、操作数、方法出口等);
(2)jvm(虚拟机)为每个线程创建一个栈(每个程序的执行都会创建很多线程),用于存放该线程执行方法的信息(实际参数局部变量等);
(3)栈属于线程私有,不能实现线程间的共享
(4)栈的存储特性是先进后出,后进先出;
(5)栈是由系统自动分配,速度快,栈是一个连续的内存空间
每调用一个方法就会创建一个栈帧。
是不是异常形象。。
(2)堆区:
1.存放创建好的对象和数组(数组也是对象);
2.jvm只有一个堆,被所有线程共享;
3.堆是一个不连续的空间,分配灵活,速度慢;
3.方法区(也在堆区里边只是方法特殊)
1 . jvm只有一个方法区;
2.实际上也是堆,只是用于存储类,常量相关信息;
3.用来存放程序中不变或者唯一的内容(类信息,静态变量,字符串常量等)
接下来是一个例子来解释上述三种内存空间:
public class oj1{
int id;
String name;
int age;
computer comp;
void study()
{
System.out.println("谁他妈买"+comp.brand);//对应下面图片的我在认真学...
}
void play()
{
System.out.println("我在斗地主");//对应下面图片的我在玩游戏...
}
oj1()//构造方法,用于创建类对象
{
}
public static void main(String[] args)
{
oj1 c1=new oj1();
computer stu=new computer();
stu.brand="小米";//对应联想
p.comp=stu;
c1.study();
}
}
class computer{
String brand;//电脑品牌
}
上图可以这么分析,main方法进栈,然后当我们创建一个对象时就会调用对象的构造函数来开辟空间,将对象数据存到堆区中,与此同时在栈内存中生成对应的引用c1引用的是oj1的对象,stu是oj1这个类的成员comp的引用,当我们在后续代码调用的时候用的都是栈内存的引用。同样也可以看出来如果属性是基本数据类型那么会和对象一起存放在堆区,如果属性是对象的引用那么此时的对象只包含引用,所引用的对象会在堆区的另一个空间
1.两种垃圾回收机制和原理:
java不同与c++的是java不用程序员手动释放用完的对象系统自动回收
归功于下面两种算法
(1)引用计数法:
堆中每个对象都有一个引用计数,被引用一次计数加一,引用变量为null则计数减一,直到为0表示无用对象,但对循环引用的无用对象无法识别(如下图)
public class oj1{
String name;
oj1 friend;
public static void main(String[] args) {
oj1 p1=new oj1();
oj1 p2=new oj1();
p1.friend=p2;
p2.friend=p1;
p1=null;
p2=null;
}
}
(2)引用可达法:
程序把所有==引用关系看作一张图==,从第一个节点开始,寻找对应的引用节点,当所有引用节点寻找完毕后,剩余节点被认为是没有引用的节点,即无用节点系统自动清除(简单来说就是如果一个对象没有被到达即没有被使用,就会被认为是无用节点);
对垃圾回收机制的简单理解
1.对局部变量的回收
(1)对局部变量:一般局部变量会跟着方法的结束出栈而被回收
(2)对堆区的对象:如果没有引用指向那么系统就会认为是垃圾被回收
(3)对象里边的属性:会随着对象的回收而回收