GC如何判断对象可以被回收

1.引用计数法

每个对象多有一个引用计数的属性,每次新增一个引用的话计数器都会加一,应用释放的时候这个计数的属性会-1,单计数为零的时候就可以被回收,不过在JAVA中不是采用该方法,一般是在Python,go,为什么java不采用该方法,是因为java中存在对象相互引用循环依赖的情况,比如A引用了B,B又引用了A,这样相互引用,即使A,B都不使用了,但因为相互引用到时计数器的值永远大于零导致无法回收,所以java是使用下面的方法的

2.可达性分析法

即从GC Root根开始向下搜索,搜索所走过的路径被称为引用链A->B->C->D,当一个对象到GC Root没有任何引用链即不可达的时候,不如A到B之间的引用链断开了,B到达不了GCRoot的根,就证明这个对象是不可用的,虚拟机则判断是可以回收的,所以BCD都可回收

什么是GCRoot?

1.虚拟机栈,即栈帧中的本地变量表中的那个引用对象
2.方法区中静态属性的一个引用的对象
3.方法区中常量的引用对象
4.本地方法栈中的JNI,一般说的是Native方法中应用的对象就是我们GC Root根

假如说引用链断了B会被马上回收吗

需要进行2次分析才会被回收,即可达性算法中的不可达对象,并不是说立即死亡,对象有一次自我拯救的机会,
一个对象要被系统标记死亡的话至少要经历两次标记的过程,
第一次:经过可达性分析算法发现并没有与GCRoot相连接的引用链
第二次:由虚拟机自动建立的这个Finalize中判断是否需要执行finalize()方法,即当对象成为GCRoot根不可达时那么GC会判断这个对象是否覆盖了finalize()这个方法,若没有直接回收,若果覆盖了还要看这个对象是否执行finalize()方法,因为对象只能触发一次finalize()方法,没有执行的话会将对象放入到F-Queue队列中,然后等待执行,如果引用了其他对象那么就会被复活了,GC再次判断对象是否可达。

MySql分库分表

减少数据库的压力
缩短标的操作时间

数据切分

数据源管理

系统应用层面

客户端模式
中间代理模式:在数据集群前加一层数据代理

中间件层面