map的遍历
用foreach遍历
HashMap<Character,Integer> map = new HashMap<>();
map.put('A',2);
map.put('B',3);
map.put('C',3);
for (Map.Entry<Character,Integer> entry: map.entrySet()) {
char key = entry.getKey();
int value = entry.getValue();
System.out.println(key+" "+value);
}
反射
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。
应用场景
1、JDBC中,利用反射动态加载了数据驱动程序,使用Class,forName()通过反射加载数据库的驱动程序
2、Web服务器中利用反射机制调用了Servlet的服务方法
3、Eclispe等开发工具利用反射动态刨析对象的类型和结构
4、Spring框架,Spring通过XML配置模式装载bean的过程
获取反射的三种方式
public class Student{
private int id;
String name;
protected boolean sex;
public float score;
}
public class Get{
//获取反射的三种方式
public staic void main(String[] args) throws ClassNotFoundException{
//方式一:通过建立对象
Student stu = new Student();
Class classobj1 = stu.getClass();
System.out.println(classobj1.getName());
//方式二:通过路径实现反射
Class classobj2 = Class.forName("fanshe.Student");
System.out.println(classobj2.getName());
//方式三:通过类名实现反射
Class classobj3 = Student.class;
System.out.println(classobj3.getName());
}
}
GC
在JVM中,有一个低优先级的垃圾回收线程,在正常情况下不会执行,只有在当前堆内存不足或者虚拟机空闲的情况下,才会触发执行,扫描那些没有任何引用的对象,并对他们进行回收。
垃圾回收的时机:
1、显式调用System.gc();
2、由JVM垃圾回收机制决定(a 内存不足,触发GC;b finalize()方法)
垃圾回收策略:
1、引用计数算法:
- 添加一个引用计数器,调用+1,引用失效-1,为0回收
- 不能解决对象之间互相引用的问题
2、可达性分析算法(GC Roots)
需要垃圾回收的内存
1、方法区(1.7)/元空间(1.8)
2、堆(GC堆):Java堆可以细分为
- 新生代(Young Generation):新生代又可分为Eden区和Survivor区
新生代的垃圾回收称为:Minor GC或者Young GC;
新生代的垃圾回收指发生在新生代的垃圾回收,因为新生代对象具有朝生夕灭的特性,所以Minor GC非常频繁,一般回收动作也快
- 老年代(Old Generation)
老年代垃圾回收称为:Major GC
出现Major GC,一般都会伴随着至少一次的Minor GC
Major GC一般比Minor GC慢十倍以上
垃圾回收算法
1、标记清除算法(Mark-Sweep):老年代算法
2、标记整理算法(Mark-Compact):老年代算法
3、复制算法(copying):新生代算法
4、分代收集(Generation Collection)
垃圾收集过程
垃圾收集造成的影响
1、STW:用户线程暂停
在垃圾收集器中,并发和并行的概念有所不同
并行:指的是多条垃圾收集线程同时执行,用户线程处于等待状态
并发:指用户线程和垃圾线程同时执行(不一定同时执行,也有可能是交替执行),用户线程继续执行,垃圾收集器在另一个CPU上
2、评判垃圾收集器的指标:吞吐量和用户体验
吞吐量:吞吐量=运行用户代码的时间/(运行用户代码的时间+垃圾收集的时间)
停顿时间/用户体验:GC造成的用户线程单次停顿时间和总的停顿时间
用户体验优先和吞吐量优先是成反比的关系
垃圾回收器
Serial (复制算法,STW):最早的单线程串行垃圾回收器。
ParNew (复制算法,STW):是 Serial 的多线程版本。
Parallel Scavenge (复制算法):Parallel 和 ParNew收集器类似是多线程的,但 Parallel Scavenge 是吞吐量优先的收集器,可以牺牲等待时间换取系统的吞吐量。
Serial Old (标记-整理法):Serial 垃圾回收器的老年版本,同样也是单线程的,可以作为 CMS 垃圾回收器的备选预案。
Parallel Old (标记整理法):Parallel Old 是 Parallel 老生代版本,Parallel 使用的是复制的内存回收算法,Parallel Old 使用的是标记-整理的内存回收算法。
CMS (标记-整理法):一种以牺牲吞吐量为代价来获得最短回收停顿时间为目标的收集器,非常适用 B/S 系统。
G1 (标记-整理法 + 复制算法):一种兼顾吞吐量和停顿时间的 GC 实现,是 JDK9 以后的默认 GC 选项。
CMS(老年代收集器,结合新生代收集器Serial和ParNew收集器一起使用)
四个步骤:
- 初始标记: 初始标记标记一下GCRoots可以关联到的对象,
STW
,整个过程很快 - 并发标记: 这个阶段紧随初始标记阶段,在“初始标记”的基础上继续向下追溯标记。注意这里是并发标记,表示用户线程可以和 GC 线程一起并发执行,这个阶段不会暂停用户的线程哦。
- 重新标记: 修正并发标记阶段,因为用户线程也在并发执行,所以导致原本没有被GCRoots关联的对象又被关联起来了,需要重新标记,
STW
,比初始标记长,比并发标记时间短 - 并发清除: 并发的清除标记的对象,应用线程和GC清除线程可以一起并发执行
缺陷:
- 内存碎片
- 更多的CPU资源
- 需要更大的对空间
CMS使用“标记-清除”算法进行的垃圾回收
CMS从全局来看,CMS收集器的内存回收是和用户线程一起并发执行的。
G1(全局收集器)
四个阶段:
- 初始标记: 和CMS不同,不用STW,和MinorGC一起发生(G1触发MinorGC时,同时将老年代的标记给做了)
- 并发标记: G1和CMS做的事情一样,不过G1多做了一件事情,在并发标记阶段,如果发现哪个Tenured中对象的存活几率很小或者没有对象存活,那么G1在这个阶段就会把他回收掉,不用等后面的筛选回收阶段;同时,在这个阶段,G1还会计算每个region的对象存活率,方便后面筛选回收阶段使用
- 最终标记: 和CMS重新标记一样
- 筛选回收: G1没有CMS的并发清除,而是筛选回收,G1挑选出在并发标记阶段计算出的存活率低的region对象进行回收,这个阶段也是和MinorGC一起回收的
G1从整体来看是基于标记-整理 算法实现的回收器,但从局部(两个Region之间)上看又是基于 标记-复制 算法实现的
FULL GC
Full GC是针对整个新生代、老生代、元空间(metaspace,Java8以上版本取代perm gen)的全局范围的 GC。Full GC不等于Major GC,也不等于Minor GC + Major GC,发生Full GC需要看使用了什么垃圾收集器组合,才能解释是什么样的垃圾回收。