让你第一次认识到Java的内存管理

发现之前写的可读性不好,这次准备试试换风格,去掉长篇大论,觉得这个风格好的,麻烦点个赞啦

清理、JVM的妙处

大家以后都是程序员,假设你很不幸,需要自己交钱租房子。

你作为一个小穷人,租的房子到期了(万一是你跳槽去了其他地方,滑稽),房子就要还给房东。

在很久之前,**房东C++**是个好人,等着房客主动来还房子,然后再把房子租出去(析构)。

这里C++只是说在堆上分配内存,而不是栈,求C++大佬们放过!!对不起!

后来叫Java的也来做了房东,Java很有钱,他有一栋大楼的房子,Java会给所有的租客一个叫内存的卡(new操作):

  1. 在客户多的时候,定期给租期还没到的人发新卡分配住处
  2. 在客户少的时候,Java就会喊所有人以及他认识的租客(活对象、引用链)来前台,给他们的卡上做个标记,这时溜号的人就没有这个标记,然后Java会把没有这个标记的人的房间重置用来下次租。

上面两种方式就是C++中的析构(还房子)与**Java的内存管理方式——垃圾回收(GC)**中的两种方式“停止-复制”与“标记-清扫”。

但是,Java有一些客户,是从C++和其他房东那里,借用客户的关系挖来的,他们的房子并不是领卡的(不用new的方式获得内存),或者做了其他影响全局的操作,比如给门上画了涂鸦(如”绘图“)。这Java就头疼了,但是聪明的Java也有他的办法,Java允许他的客户有一个私人的小服务员finalize(),这个客户走的时候,就会招呼这个服务员,这个服务员就在房间里面等着,Java老板来了的时候,服务员就开始干房客交待的事情。同时大老板Java在自己的F-Queue队列小本上记上这个房间,先去回收没有服务员的房间去了,稍后再来看这个房间。诶,万一这个房客交待服务员finalize()做的事情,是把房间送给其他的房客(重新与引用链上的对象建立关联),那我们就不能回收了对吧,一个房间就“起死回生”,Java会把它从本本上划去

看到这里,可以做一个书面总结

  1. 使用对象需要内存,Java使用了自动的垃圾回收技术,回收由new创建的对象,同时Java语言只能用new初始化对象(注意是Java语言)
  2. 对象可能不被垃圾回收
  3. 垃圾回收、finalize()并不等于“析构”
  4. 垃圾回收只与内存有关。(只是为了腾开空间)

何时使用finalize()方法?

只在回收内存的时候使用,虽然Java会回收所有对象,但是C语言或者其他语言申请的内存空间,Java就束手无策,需要用finalize()方法

另外,JAVA虚拟机只能保证finalize()方法的执行,但是并不能保证它的完成!(防止阻塞)

除此之外,你还可以?

利用finalize()方法判断当前对象是否能被终结,下面是例子

class Book{
	boolean check=true;
    protected void finalize(){
        if(check)
            System.out.println("Error:the check is true");
        super.finalize();
    }
}

在这个例子中,我们要求书在被删去的时候,check是true,这样不符合的就会打印出错误

这里还使用了super.finalize()方法,super是父类对象的引用,调用这个可以使基类的一些操作也能被执行。

垃圾回收器的初识

C++的内存就像院子,用完了,整个院子都会消失

而Java所有的对象都只能使用new来创建,全部存储在堆上。

这并不会影响Java的速度,因为Java的内存采用的类似传送机一样的结构,Java的堆指针只是简单地移动到未分配的区域,效率很高。同时,垃圾回收器在工作的时候,一面回收空间,一面使堆中对象紧凑排列,这使得Java的内存分配速度十分高速高效。

另外,根据上面谈到的Java回收内存的两种方式,指的是“停止-复制”和“标记清理”,这是Java垃圾回收的四种算法的一部分,其他的不做深度阐述。

posted @ 2020-03-22 22:35  jirath  阅读(190)  评论(0编辑  收藏  举报