2022.1.4Java基础-构造方法、内存管理

构造方法重载

含参不含参

public class Point {
    double x,y;

    Point(double _x,double _y){
        x=_x;
        y=_y;
    }

    Point(){

    }
}

Java虚拟机内存模型

虚拟机的内存可以分为三个区域:栈stack、堆heap、方法区method area

栈:

栈里放的是要执行,或者正在执行的方法

  1.  虚拟机会为每一个进入栈的方法分配一个栈帧
  2. 虚拟机为每一个线程创建一个栈,用于存放该方法的信息(局部变量、实际参数)
  3. 栈属于线程私有,不能实现线程之间共享
  4. 栈的存储特性:“先进后出,后进先出”
  5. 栈是由系统自动分配,速度快,栈是一个连续的内存空间

堆:

堆里放的是创建好的对象和数组(数组也是对象)

  1. 虚拟机只有一个堆,被所有线程共享
  2. 堆在内存的存储方式是不连续的,所以分配灵活,速度慢
  3. 堆被所有线程共享,被创建很多个对象,垃圾回收器会做进一步规划,把长时间不用的对象回收,就被划分为年轻代、老年代

方法区:

方法区里放着的是唯一的实体代码,也就是各种蓝图(类)、常量池、静态的类、方法

扫描二维码关注公众号,回复: 16279931 查看本文章
  1. 方法区是javaJVM的规范,可以有不同的实现
    1. JDK7以前是“永久代”
    2. JDK7部分去除“永久代”,静态变量、字符串常量池都挪到了堆内存中了
    3. JDK8是“元数据空间”和堆结合起来,但依然存在
  2. JVM只有一个方法区,被所有栈共享
  3. 方法区实际也是堆,只存储类、常量相关的信息
  4. 存放永远不变的内容,类信息、静态变量、字符串、常量等
  5. 常量池中主要存放:字符串、final常量值

垃圾回收机制

Java引入垃圾回收机制,就是为了提高开发效率,程序员不需要过多的注重内存管理机制

内存管理

内存管理很大程度就是:堆中对象的管理,包括对象空间的分配和释放

对象空间的分配:使用new关键字创建对象

释放:把对象赋值null即可

垃圾回收过程

任何垃圾回收算法一般做两个事:

  1. 发现无用的对象
  2. 回收无用对象占用的空间

发现是由java的垃圾回收器通过相关算法发现无用对象、进行清除整理。

垃圾回收相关算法

  1. 引用计数算法
  2. 引用可达法(根搜索算法):也就是从一个节点GC ROOT(当前时刻存活的对象)开始,找对应的引用节点,然后在找到的这个节点上再找引用节点,直到所有节点都没引用了,其他的节点就被视为无用节点。

大概说一下引用计数算法

就是创建的每个对象都有一个引用计数,每有一个变量引用了该对象,引用数加1,取消引用了(null),引用数-1

特殊情况:这种垃圾无法识别

对象AB互相引用,即使外面ObjA、B停止引用了,但他俩换在互相引用,识别不了

 通用的分带垃圾机制

 这是在堆里面的东西,现在Edem区存放对象,执行一次Minor GC,清理年轻代,然后Edem区的无用对象会被清理,有用对象会到下一个survivor区,然后在1区,再执行Minor GC,清除无用对象转至2区,然后再转回1区,连续15次以上,就会被转入年老代,通过Major GC清理

Full GC清理年轻代、年老代、和永久代(里面存着类信息,静态区等等)

内存泄露

指堆内存中由于某种原因程序未释放,造成内存浪费,导致运行速度减慢甚至系统崩溃

原因

1.创建大量无用对象

 2.静态集合类的使用

就是大量使用static标签,这些对象或者方法属性长时间不会被释放

3.各种连接对象(IO流对象、数据库连接对象、网络连接对象)未关闭

4.监听器的使用不当

其他要点

  1. 程序员无权调用垃圾回收器
  2. 程序员可以调用System.gc(),该方法只是通知JVM,并不是运行垃圾回收期(Full GC)。尽量少用,会申请Full GC,成本高,影响系统性能
  3. Object对象的finalize方法,是Java提供给程序员用来释放对象或资源的方法,但尽量少用

this

在每一个对象里都有一个this,他存储着自身对象的地址,调用this.属性就是调用自身,这在方法中会使用,传入的参数复制给this.属性

static

带有static标签的属性和方法属于类,属性不会随着对象的创建而创建,在程序的开始会自动创建类信息里面会带着static的属性、方法

静态初始块

public class TestStatic {
    int id;
    String name;

    static String company = "北京尚学堂";
    static {      
                                          
    //通过static{}来对静态属性初始化赋值

        System.out.println("执行类的初始化工作");
        company="腾讯山西太原分部";
        printCompany();
    }
    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(company);
    }

    public static void main(String[] args) {
        TestStatic u = new TestStatic(101,"张小八");
        TestStatic.printCompany();
        TestStatic.company="北京腾讯分部";
        TestStatic.printCompany();
    }
}

变量的分类和作用域

局部变量、成员变量、静态变量核心区别
类型 声明位置 从属于 声明周期(作用域)
局部变量 方法或语句块内部 方法/语句块 方法调用结束

成员变量

(实例变量)

类内部、方法外部 对象

对象创建,成员变量随之创建

对象消失,成员变量随之消失

静态变量  

(类变量)

类内部、static修饰 类被加载,静态变量就有效

包机制

就是文件夹,用于管理类、解决重名问题

package point;

 final关键词

 认识Object.toString()、重写

public class TestObject extends Object{
    String name;
    String pwd;

    @Override
    public String toString() {
        return  "name='" + name +", pwd='" + pwd ;
    }

    public static void main(String[] args) {
        TestObject a = new TestObject();
        System.out.println(a);
    }
}

==和Object.equals()

"=="代表双方是否相同,如果是基本类型就是值相等,如果是引用类型就是地址相等,就是表示是同一对象。

equals()默认和==是一样的,但是对这个方法进行重写,比如比较两个对象的所有属性是否相同,是就说这两个对象是相等的。

关键字super

 .

先调用了父类子类的static();

 访问权限修饰符

 

 

接口

jdk8以后,接口允许默认方法,静态方法

默认方法

public interface TestDefault {
    void printInfo();

    default void more(){
        System.out.println("more,测试默认方法");
    }
}


class TestDefault1 implements TestDefault{


    @Override
    public void printInfo() {
        System.out.println("通过接口实现的方法");
    }

    @Override
    public void more() {
        System.out.println("我重写了more默认方法");
    }
}

猜你喜欢

转载自blog.csdn.net/qq_41302243/article/details/122298894