OOP-20年秋第二周

Java第二周:

C是面向过程的 C++是面向对象的(混合)
在这里插入图片描述

  1. 可以叫Java是C-plus-plus的minus-minus版本
  2. System.out.println()
    –System是个类,Out是个对象,println是个方法
  3. 对javase来说rt.jar很重要
    –在jre/lib里面的runtime.jar,包含了System.class
  4. Portable by jvm
  5. 强类型语言 声明变量要先使用
  6. 虽然我们说everything is an object
    –但是有些基本类型不是对象
  7. Java在语言级支持多线程
    –Java依赖于虚拟机 而C这种靠的是OS
    –线程合体 = 进程 线程比较小可独立运行
    –方便进程与系统去管理他们,缺少一个线程 经常依旧运行其他的线程
    –线程在代码里面是什么?
    –比如一个等待响应的代码,如果有多个数据要等,那一个个等太耗时间,这个时候使用多线程可以同时等待
  8. 可以使用Java监视和管理控制台来看jvm
    –在jvm中就是需要很多的线程来支持,这样,除了出事的线程外,该干干嘛
    –但是 高并发的debug很容易不可再现!
  9. 在rt.jar的concurrent可以看到多线程包

在这里插入图片描述

  1. 垃圾回收-内存管理
    –垃圾回收避免内存泄漏,但是也不是完全避免哈~
    –栈的引用指向了堆的东西 就是可达的,而不可达的就是没用的
    –而实现的理解就是 有个计数器 当一个对象的引用计数为zero 就无用了
    –gc就会想办法把他回收掉
    ----什么是内存泄漏?
    –useless的对象 却是reachable的,这样就没被gc回收掉

  2. 如果有一组堆内互相指向对方的对象
    –没有’外力’拉着他们 依旧会gc回收
    ----能提供外力的是什么?
    –Gc Roots
    –可以理解为栈的引用拉着堆内的对象
    –可以用可视化工具来侦查源头(回溯)

  3. 访问范围修饰符:
    –public> ’ ’ >private>protected
    –Top class only use public and none
    –Inner class可以用private

  4. 为什么要封装类?
    –为什么System类是private的?
    –因为不想要你用啊!!,只让你调用系统的方法,不给你整对象

  5. Object类非常最要
    –it is a root of the class hierarchy
    –在Object中public方法在任何类都可以用
    –getclass()
    –toString()【return 类名+@+hashcode】
    –equals()【比较的是地址】
    –hashcode()【return 地址【
    –notify()*2
    –wait()*3
    –finalize()

  6. 要知道Object中缺省的方法是什么 然后知道如何去修改他们

  7. 大小写敏感的java真的很敏感的呢

  8. Main方法的签名是必须的 而传入的数组是get命令行的option

  9. Primitive数据类型
    –引用类型有无穷种
    –int4 byte1 short2 long8
    –float double
    –boolean char2

  10. Java的字符对Unicode很支持
    –每个字符对应唯一的符号
    –GB1312是JAVA不支持的嘛?
    –桂老板解答了,JAVA内部都是unicode,导入的时候会自动转码

  11. Boolean存的就是true和false
    –(最好不要用0和1)

  12. 对11与12进行补充:

可达性分析解决的问题

垃圾回收的可达性分析算法:解决了循环引用导致引用计数失效的问题。引用计数可以类比为:几个重物之间互相用绳子连起来,记录每个重物所连接的绳子数。当某个重物所连接的绳子数不为0时,判断重物没有落地(落地就是被垃圾回收)。但是这样的问题在于,如果几个重物存在循环引用,而没有稳定向上的拉力,重物本应该落地,但是因为引用计数不为0,导致没有落地。如图所示:、
在这里插入图片描述
由此可见,垃圾回收可以有一个新的思路:从稳定的拉力源开始往下找,查看对象是否可以访问到。**如果不能访问到,说明对象也不能被利用了,就被回收掉。这里的“稳定的拉力源”,被称为根集(GC Roots)。一般来说,GC Roots有几种来源:
1.虚拟机栈中的引用的对象
2.方法区中的类静态属性引用的对象
3.方法区中的常量引用的对象
可以看到,栈帧随着函数的执行会弹出,所以局部变量的引用在函数执行结束后就没了,对象也随之被回收;方法区因为作为持久带,很少做垃圾回收,所以静态属性引I用的对象总会有一个稳定的拉力来源,用多了就容易造成内存泄漏。

可达性分析过程

Java所有类的祖宗类Object中有一个方法,叫做 finalize(),也就是说,所有类的对象中都会有这么一个函数,这个函数在垃圾回收中起作用。事先说明一 点: finalize()很不可靠,不要人为调用它。由GC自动调用。finalize主要为GC做一些清除或清扫工作。
1.从GC Roots中的引用出发,按照路径往下找,记 录可到达对象;扫描完毕后,可以发现不可达对 象。这一步叫做可达性分析;
2.不可达的对象,并不马上被垃圾回收,后面还要经 过两次标标记;
3.第一次标记:查看对象是否有必要执行finalize(),如果有必要执行,则调用;如果没有必要,则直接回收,进行第一次标记(没必要执行的情况是:如果对象所在类没有重写finalize(),或者finalize(已经被执行过);
4.如果对象被判定为有必要执行finalize(),则这些对象被放进个队列——F-Queue,虚拟机会建—个优先级很低的线程——Finalizer,去一个个调用这些对象的finalize()方法。但是GC并不承诺会等finalize()全部执行结束才回收对象,因为 finalize()内部可能会出现死循环的情况。
5.如果finalize()执行完了,对象经历了两次标记,那就死定了,会被垃圾回收掉。
那么,如何利用finalize()从垃圾回收流程中逃出去? 在此过程中重新找个对象指向此对象就可以。

代码例子:

public class FinalizeTest {
	public static Myclass reference =null;
	@Test
		void Test() throws InterruptedException {
			FinalizeTest.reference = new Myclass();
			FinalizeTest.reference = null;
			system.gc();
			Thread.sleep(500);
			if(FinalizeTest.reference !=null){
				system.out.println("I am still alive! ");
			}else{
				system. out.println("I am dead! ");
			}
		//再来一遍
			FinalizeTest.reference = null;
			system.gc();
			if(FinalizeTest.reference != null){
				system.out.println("I am still alive! ");
			}else{
				system.out.println("I am dead! ");
			}
	}
}
class Myclass{
	public int status = 1;
	@override
	protected void finalize() throws Throwable {
		super.finalize();
		system.out. println("finalize(执行完毕.............");
		FinalizeTest .reference = this;
		//将当前对象连接到方法区的静态变量
	}
}

运行结果:
在这里插入图片描述
可以看到,第一次逃掉了,第二次因为finalize()已经被执行,所以直接被垃圾回收了。

25.纠错1.0
在这里插入图片描述
26.纠错2.0
首先是判断为不可达,并且finalize方法没有被重写,这两个条件都要被满足,才会放到f-queue里面等待被finalizer执行finalize。
这样做的逻辑在于,如果用户自己重写了finalize,意味着他想做一些自定义的清理工作,放到finalize里面。如果没有重写,原本的这个方法什么也不会做,并且此时如果判断不可达,那就可以直接回收掉。
需要第二次标记的原因是,gc会跑上去瞄一眼,如果标记了两次那就直接吃掉,如果此时对象被标记了一次之后自救了,那还是可以复活。
如果第二次运行的时候,看到标记1就立马吃掉,那就不能复活了。
直接回收的条件:

  1. 不可达
  2. 没有override finalize方法
    但是,gc只是个扫地机,不太能相信,害怕的话建议自己去执行。
    此外,就算你写个死循环,时间太长了gc也会干掉你的对象。
    而且你也不能无限标记无限复活,gc只给你一次面子。

(有错就改,希望大家多提意见)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值