学习大纲
- 分代垃圾回收机制
- this的本质(用于对象的)
- 创建一个对象分为如下四步
- static(静态的)关键字
学习笔记
分代垃圾回收机制
基于的事实:不同的对象的生命周期是不一样的,因此,不同的生命周期额的对象可以采取不同的回收算法,以提高效率。
对象分为:年轻代、年老代、持久代。
JVM将堆内存划分为:Eden、Survivor、和Tenured/Old
1.年轻代
所有新生成的对象首先是放在Eden区。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象,对应的是Minor Gc,每次Minor Gc会清理掉年轻代的内存,算法采用效率较高的复制算法,频繁的操作,但是会浪费内存空间。当“年轻代”区域存放满对象后,就将对象放到年老代区域
2.年老代
在年轻代中经历了N(默认15)次垃圾回收后仍然存活的对象,就会放到年老代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象。年老代对象越来越多,我们就需要起到Major Gc和Full Gc(全量回收),来一次大扫除,全面清理年轻代区域和年老代区域
3.持久代
用于存放静态文件,如java类,方法等,持久代对垃圾回收没有显著影响
垃圾回收过程:
1.新创建的对象,绝大多数都会存储在Eden中,
2.当Eden满了(达到一定比例)不能创建新对象,则出发垃圾回收(Gc),将无用对象清理掉,然后剩余对象复制到某个Survivor中,如S1,同时清空Eden区
3.当Eden区再次满了,会将S1中的不能清空的对象存到另外一个Survivor中,如S2,同时将Eden区中的不能清空的对象,也复制到S1中,保证Eden和S1,均被清空
4.重复多次(默认15次)Survivor中没有被清理的对象,则会复制到老年代Old(Tenured)区中,
5.当Old区满了,则会出发一个一次完整地垃圾回收(FullGc),之前新生代的垃圾回收称为(Minor Gc)
关于this
关于成员变量与局部变量相同时,采用就近原则
对象创建的过程:
1.分配对象空间,并将对象成员变量初始化为0或空
2.执行属性值的显式初始化
3.执行构造方法
4.返回对象的地址给相关变量
This的本质
This的本质就是“创建好的对象的地址”!由于在构造方法调用前,对象已经创建好了。因此在构造方法中也可以使用this代表“当前对象
this最常的用法:
1.在程序中产生二义性之处,应使用this来指明当前对象;普通方法中,this总是指向调用该方法的对象。构造方法中,this总是指向正要初始化的对象。
2.使用this关键字调用重载的构造方法,避免相同的初始化代码。只能在构造方法中用,并且必须位于构造方法的第一句。
3.This不能用于static方法中。
关于static
Static的特点:
在类中,用static声明的成员变量为静态成员变量,也称为类变量。类变量的声明周期和类相同,在整个应用程序执行期间都有效。
static修饰的成员变量和方法,从属于类。
普通变量和方法从属于对象。
结合对应程序和内存分析去理解
代码
/**
- 测试this的用法
- @author L
*/
public class TestThis {
int a,b,c;
TestThis(int a,int b){
// a; 单纯一个a表示的是局部变量(对应参数括号中的a),就近原则
this.a=a;//程序发生二意性时,通过this区分成员变量和局部变量,this.a表示的是成员变量(直属于本类中的,即该方法所在的类中的)
this.b=b;
}
TestThis(int a,int b,int c){
//TestThis(a,b);报错,不能在另一个构造器中用这种方法(通过方法名调用)来调用另一个构造器
this(a,b);//可以通过this来调用另一个构造器,this(a,b)表示的就是调用构造器,而且这句必须在方法中的第一句
this.c=c;
//this(a,b);报错,理由如上句
}
void sing() {
}
void eat() {
this.sing();//调用本类中的sing();
System.out.println("你妈妈喊你回家吃饭!");
}
public static void main(String[] args) {
TestThis hi=new TestThis(2,3);
hi.eat();
}
}
/**
- 测试static关键字
- @author Administrator
*/
public class TestStatic {
int id;
String name;
String pwd;
static String university = “某某大学”;//大学名称
public TestStatic(int id,String name) {
this.id=id;
this.name=name;
}
public void login() {
System.out.println(“登录:”+name);
}
public static void printCompany() {
//login();调用非静态方法,报错
System.out.println(university);
}
public static void main(String[] args) {
TestStatic u = new TestStatic(101,“LLL”);
TestStatic.printCompany();
TestStatic.university=“111”;
TestStatic.printCompany();
}
//要用内存分析去理解
}