标签:方法 ash 基础功 order by list 符号 lin shc 全表扫描
ConcurrentHashMap把Map分成了几个segment,put和get的时候都根据key的hash,来计算在哪个segment中,每个segment类似于一个HashTable,都是线程安全的
(1) java中,如果有一个类用来存放其他类的对象,这个类就叫容器,或者集合。集合就是讲若干性质相同或相近的类集合在一起而形成的整体。
之所以需要容器,是因为数组的长度难以扩充,数组中数据类型必须相同
(2) 容器和数组的区别
ArrayList基于数组,查找速度比较快,LinkedList基于链表,增删操作比较快
Collections.synchronizedList(new ArrayList());
Collections.synchronizedSet(new HashSet());
程序计数器是一块较小的内存空间,可以看做是当前线程所执行的字节码的行号指示器。分支、循环、异常跳转等基础功能依靠它。
如果执行的是一个Java方法,计数器记录的是正在执行的虚拟机字节码指令的地址;如果执行的是一个本地方法,这个计数器为空。
线程私有,生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的同时都会创建一个栈帧,
用于存放方法的局部变量表,操作栈,动态链接,方法出口等信息,Java方法从调用直至执行完成,就是一个帧栈在虚拟机栈中的入栈出栈过程
操作数栈:和局部变量表一样,操作数栈也是被组织成一个以字长为单位的数组,但是不是通过索引来获取值,是通过入栈、出栈来进行数据的
访问。
动态链接:虚拟机在运行时,常量池会保存大量的符号引用。如果是在类加载阶段或者第一次使用时转化为直接应用,则成为静态解析,
否则 成为动态链接。
返回地址:一种是正常退出,退出后会根据方法的定义来决定是否要传返回值给上层的调用者,一种是异常导致的方法结束,这种情况是不会传返回值给上层的调用方法。
方法的的一次调用就对应着栈帧在虚拟机栈中的一次入栈出栈操作,因此方法退出时可能做的事情包括:恢复上层方法的局部变量表以及操作数栈,如果有返回值的话,就把返回值压入到调用者栈帧的操作数栈中,还会把PC计数器的值调整为方法调用入口的下一条指令。
与虚拟机栈类似,虚拟机栈是为了执行Java方法而存在的,本地方法栈是为了执行native方法入栈出栈的
是JVM所管理的内存中最大的一块。被所有线程共享,在虚拟机启动时创建,用于存放对象实例,-Xms(最小值)和-Xmx(最大值),默认是计算机物理内存的1/64
堆是GC主要活动的区域,因为GC基本采用分代收集算法,因此又分为新生代和老年代。新生代,程序新创建的对象都是从新生代分配内存,经过多次GC仍然存货的对象会进入老年代,
新建的对象也可能直接进入老年代,大对象或者大的数组对象,且数组内部无引用外部对象
存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
GC一般系统随机触发以及system.gc(),且当eden分配新对象而内存不足时触发minorgc,或者eden向old转移但是old内存不够时触发fullgc
对于新生代,一般采用复制算法,一般内存划分为一个较大的eden和2个survivor,每次使用eden和1个survivor,默认8:1,每次讲eden和survivor中存活的对象存入另一个survivor,
需要老年代担保(Handle Promotion)
对于老年代,一般采用标记-整理算法,讲可用对象向内存的一边偏移,然后清除掉边界以外的内存
可以通过引用计数器来判断,但是无法解决循环引用的问题
可达性分析法,GC root与这个对象没有可达路径
循环引用demo如下
Class C { public Object x; } C obj1、obj2 = new C(); obj1.x = obj2; obj2.x = obj1; obj1、obj2 = null;
这种情况下,obj1和obj2的计数器都不为0
标签:方法 ash 基础功 order by list 符号 lin shc 全表扫描
原文地址:https://www.cnblogs.com/njuwanghan/p/9068508.html