空闲列表:堆内存不规整
并发问题
同步:采用CAS配上失败重试的方式保证更新操作的原子性
把内存分配动作按照线程划分在不同的空间之中进行
将分配到的内存空间都初始化零值
设置对象的类实例、元数据、哈希码、GC分代年龄等信息。
执行方法
对象的内存布局
对象在内存中储存的布局可以分为3块区域:
对象头
对象运行时数据、哈希码、GC分代年龄、锁状态标记、线程持有的锁、偏向线程ID等
类型执行:即对象执向它的类元数据的指针,指明对象数据哪个类的实例。
实例数据
对象真正存储的有效信息
对齐填充
占位符作用
对象的访问定位
句柄定位
直接指针
垃圾收集器
程序计数器、虚拟机栈和本地方法栈这三个区域属于线程私有的,只存在于线程的生命周期内,线程结束之后也会消失,因此不需要对这三个区域进行垃圾回收。垃圾回收主要是针对 Java 堆和方法区进行。
判断对象是否死亡
引用计数算法
给对象添加一个引用计数器,每当有一个地方引用它,计数器值就加1;引用时效时,计算器值就减1;当计数器值为0的对象就是不可能再被使用的。
当两个对象相互引用时,此时引用计数器的值永远不为0,导致无法对它们进行垃圾回收。
public class ReferenceCountingGC {
public Object instance = null;
public static void testGC() {
ReferenceCountingGC objA = new ReferenceCountingGC();
ReferenceCountingGC objB = new ReferenceCountingGC();
objA .instance = objB ;
objB .instance = objA ;
objA = null;
objB = null;
System.gc();
}
}
可达性分析算法
以GC Roots为起始点,从这些节点开始向下搜索,能够搜索到的对象都是存活的,不可达的对象则为不可用。
在Java语言中,可作为GC Roots的对象包括下面几种:
虚拟机栈中引用的对象
方法区中静态属性引用的对象
方法区中常量引用的对象
本地方法栈中Native方法引用的对象
引用类型
无论是引用计数算法还是可达性分析算法判断对象是否存活都与引用有关。在JDK1.2之后,Java对引用的概念进行了扩充,划分为强度不同的四个的引用类型。
强引用
通过new来创建对象的引用类型,被强引用的对象永远不会被垃圾收集器回收。
Object obj = new Object();
软引用
通过SortReference类来实现,只有在内存不足的时候才会被回收。
Object obj = new Object();
SoftReference sr = new SoftReference(obj);
obj = null;
弱引用
通过WeakReference类来实现,只能存活到下一次垃圾收集发生之前。
Object obj = new Object();
WeakReference wr = new WeakReference(obj);
obj = null;
WeakHashMap 的 Entry 继承自 WeakReference,主要用来实现缓存。
private static class Entry<K,V> extends WeakReference implements Map.Entry<K,V>
Tomcat 中的 ConcurrentCache 就使用了 WeakHashMap 来实现缓存功能。ConcurrentCache 采取的是分代缓存,经常使用的对象放入 eden 中,而不常用的对象放入 longterm。eden 使用 ConcurrentHashMap 实现,longterm 使用 WeakHashMap,保证了不常使用的对象容易被回收。
public final class ConcurrentCache<K, V> {
private final int size;
private final Map<K, V> eden;
private final Map<K, V> longterm;
public ConcurrentCache(int size) {
this.size = size;
this.eden = new ConcurrentHashMap<>(size);
this.longterm = new WeakHashMap<>(size);
}
public V get(K k) {
V v = this.eden.get(k);
if (v == null) {
v = this.longterm.get(k);
if (v != null)
this.eden.put(k, v);
}
return v;
}
public void put(K k, V v) {
if (this.eden.size() >= size) {
this.longterm.putAll(this.eden);
this.eden.clear();
}
this.eden.put(k, v);
}
}
虚引用
也称为幽灵引用或者幻影引用,是最弱的一种引用关系。
通过PhantomReference类来实现,为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。
总结
在这里,由于面试中MySQL问的比较多,因此也就在此以MySQL为例为大家总结分享。但是你要学习的往往不止这一点,还有一些主流框架的使用,Spring源码的学习,Mybatis源码的学习等等都是需要掌握的,我也把这些知识点都整理起来了
实现,为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。
总结
在这里,由于面试中MySQL问的比较多,因此也就在此以MySQL为例为大家总结分享。但是你要学习的往往不止这一点,还有一些主流框架的使用,Spring源码的学习,Mybatis源码的学习等等都是需要掌握的,我也把这些知识点都整理起来了
[外链图片转存中…(img-FWhFV2cJ-1714137705291)]
[外链图片转存中…(img-lDvXRzeq-1714137705291)]