垃圾回收器
垃圾收集是Java虚拟机(JVM)垃圾收集器(Garbage Collector简称GC)提供的一种用于在空闲时间不定时回收无任何印象引用的对象占据的内存空间的一种机制。
Java垃圾收集器的主要特征:
1.停止-复制(stop-copy)
2.标记-清除(mark-sweep)
3.分代(generation)
4.自适应(adaption)
停止-复制(stop-copy)
程序首先停止,然后将所有存活对象从一个堆复制到另一个堆,剩下的就都是垃圾。
当一个对象从一个地方移动到另一个地方时,所有指向该对象的引用都必须修改。
该算法的问题:
需要有两个堆,然后在这两个独立的堆之间来回复制内存,这比实际需要多了一倍内存。
一旦程序变得稳定,产生的垃圾很少,则此算法很浪费。
标记-清除(mark-sweep)
遍历所有引用以查找存活对象。找到存活对象会给该对象设置标志。
标记全完成后进行清除,没有标记的对象被释放,不会发生复制。
对于一般用途,此算法很慢,但在垃圾很少的时候,速度就快了。
分代(generation)
创建一个对象的时候,在eden区操作,当这个区满了,那么就会触发一次Young GC(年轻代的垃圾回收)
当eden区再用完,就再触发一次Young GC,此时将Eden区与From区还在使用的对象复制到to区
下一次Young GC的时候,将Eden区与To区中还在被使用的对象复制到From区
若干次Young GC后,有些对象在From区与To区之间来回游荡,一旦超出阙值,就将它们复制到老年代。
如果老年代被用完,则执行Full GC
自适应(adaption)
JVM会监控垃圾搜集的效率,去切换到“标记-清除”算法还是“停止-复制”算法。
资源清理
不要使用finalize(),用了也没用,不知道啥时候才执行,由JVM决定
finalize()的使用仅限于一种特殊情况:对象以某种方式分配存储空间,而不是通过创建对象来分配。比如在Java中通过调用C的malloc()函数来分配存储空间,此时应该在finalize()中调用C的free()函数。
感觉这边有时间还是要看看JVM,分代还是搞的不是很懂。
final关键字
final和c中的const关键字差不多,对于变量不能被修改,对于对象不能被修改引用。
使用 final 方法的原因有两个。第一个原因是给方法上锁,防止子类通过覆写改变方法的行为。这是出于继承的考虑,确保方法的行为不会因继承而改变。
过去建议使用 final 方法的第二个原因是效率。但在最近的 Java 版本中,虚拟机可以探测到这些情况(尤其是 hotspot 技术),并优化去掉这些效率反而降低的内嵌调用方法。
有很长一段时间,使用 final 来提高效率都被阻止。你应该让编译器和 JVM 处理性能问题,只有在为了明确禁止覆写方法时才使用 final。
类中所有的 private 方法都隐式地指定为 final。因为不能访问 private 方法,所以不能覆写它。可以给 private 方法添加 final 修饰,但是并不能给方法带来额外的含义。
当说一个类是 final (final 关键字在类定义之前),就意味着它不能被继承。之所以这么做,是因为类的设计就是永远不需要改动,或者是出于安全考虑不希望它有子类。
接口
Java 在设计之初,C++ 的多继承机制饱受诟病。Java 过去是一种严格要求单继承的语言:只能继承自一个类(或抽象类),但可以实现任意多个接口。
// interfaces/MultipleInheritance.java
import java.util.*;
interface One {
default void first() {
System.out.println("first");
}
}
interface Two {
default void second() {
System.out.println("second");
}
}
interface Three {
default void third() {
System.out.println("third");
}
}
class MI implements One, Two, Three {}
public class MultipleInheritance {
public static void main(String[] args) {
MI mi = new MI();
mi.first();
mi.second();
mi.third();
}
}
嵌套接口
对map进行遍历:
Mao源码:
此时Entry就是Map的嵌套接口。