堆内存和栈内存
栈内存:内存空间大小有限,是系统自动分配和释放的,先进先出的原则。是线程私有的,会造成栈内存溢出的情况
堆内存:内存空间大小无限,是手动申请和释放的,常用new一个对象来申请内存。线程共享的,主要用于数组和对象,手动申请也要手动释放,否则容易造成内存泄漏的问题
栈内存自动回收机制:通过计数使用的情况,当0的时候就被自动回收,如果出现相互引用的情况就会出现内存泄漏,堆内存是通过引用变量,变量是在栈内存中存储。
Java抽象类和接口的对比
抽象类 | 接口 | |
---|---|---|
默认实现方法 | 可以默认的实现方法 | 完全抽象 |
方式 | extends继承,子类不是抽象类,就要实现全部方法。 | implement,要实现所有的方法 |
多继承 | 可继承一个类和多个接口 | 可继承多个接口 |
Java多态
实现多态的三个必要条件:继承,重写,向上转型
实现多态的两个方法:
- 基于继承:父类和继承该父类的子类的某些方法重写,多个子类对同一个方法可以写出不同行为。
- 基于接口:接口引用必须是指定这实现了该接口的类的实例,运行时候根据对象引用的实际类型执行对应的方法。
Java垃圾回收机制
强引用:Object o = new Object()就是强引用,如果强引用还存在就不会给垃圾回收
软引用:可能还有用,但是内存不足,就会被回收
弱引用:只能存活到下次垃圾回收前
虚引用:最弱的一种引用关系,完全不会对其生存时间构成影响,无法通过虚引用来获得一个对象实例
判定是否是垃圾的算法:引用计数法,根搜索算法
回收:是清理垃圾占用的内存空间而不是对象本身
回收方法:
- Tracing标记清除算法:分为标记和清除两个阶段,标记需要回收的对象(用根搜索标记),标记完成后统一回收。
- Compacting标记整理算法:将标记后的所有垃圾对象向一段移动,然后清理掉端边界以外的内存。在基于compacting算法的收集器需要增加句柄和句柄表
- Copying算法:将内存空间分成两部分AB,每次只使用一块,假设A用完了,将A中还存活的对象拷贝到B中,然后把A清空
- Adaptive算法:监控当前堆的使用情况,并选择适当的回收算法
Java的堆内存的回收机制:
使用分代回收的方式划分为三代:新生代,老年代,持久代
因为不同的对象的生命周期是不一样的,所以分代采用不同的回收算法进行垃圾回收,提高回收效率
新生代 | 老年代 | 持久代 | |||
堆内存分块 | Heap Space | Permanent Space | |||
分代 | Eden | FormSurvivor | ToSurvivor | ||
回收 |
| 在年轻代经历了N次垃圾回收后仍然存活就会被复制到老年代中 | 主要存放的是Java类定义信息,静态类型数据。对垃圾回收没有显著影响 |
按执行机制划分Java的垃圾回收器:程序空闲时候不定时回收
- 串行垃圾回收器:适合小数据量的情况
- 并行垃圾回收器:吞吐量优先
- 并发标记扫描垃圾回收器:响应时间优先
- G1垃圾回收器
Java处理异常的机制
抛出异常:引发了异常,就创建一个异常对象。运行时,系统寻找处置异常对象的代码并处理。
捕获异常:抛出异常后,系统寻找异常处理,没有找到合适的异常处理就终止系统。
常用try catch finally来捕获异常,try捕获异常,catch处理异常,finally无论是否有异常都继续执行
四种情况下finally模块不会继续进行:
- finally模块存在错误
- 前面代码中用了System.exit()退出程序
- 程序所在的线程死亡
- 关掉CPU