1,cas本身跟自旋关系不大,一次cas要么成功要么失败,不会等待,所以非阻塞,网上铺天盖地自旋,是因为使用上要加上死循环或者尝试多次cas实现类似自旋的作用
2,非堆内存,比如元空间一般在fullgc 或者 直接内存 DirectByteBuffer等(一般也是fullgc),由程序自行释放即可
直接内存使用的本地内存不足时,java.lang.OutOfMemoryError:Direct buffer memory
元空间
元空间也是使用本地内存,java.lang.OutOfMemoryError: Metaspace
方法区的GC
常量池中废弃的变量:没有引用就回收
不再使用的类型:(判断这个条件苛刻并且费事)
该类的所有实例都被回收
加载类的加载器被回收
该类对应的Class对象没有被引用
实例对象(实例的instanceOopDesc,堆)——>实例的instanceKlass(方法区,元数据,同一个类加载器只有一份)——>实例的Class对象(实例的instanceOopDesc,堆,同一个类加载器只有一份,也反指向instanceKlass)。instanceOopDesc,只包含数据(对象头-Mark Word,元数据指针-指向方法区的instanceKlass实例,实例数据,如果是数组对象,再加上数组长度)。
所以,获取Class对象三种方式:
1.Class.forName("ClassName"),通过类的元数据的Class对象引用获得Class对象:装入类,并做类的静态初始化,返回Class的对象。
2.object.getClass(),通过实例对象保存的对类的元数据的引用获取类的元数据(instanceKlass),再通过instanceKlass中对Class对象的引用获取Class对象(instanceOopDesc):对类进行静态初始化、非静态初始化;返回引用o运行时真正所指的对象(因为:子对象的引用可能会赋给父对象的引用变量中)所属的类的Class的对象。
3.ClassName.class:通过类的元数据的Class对象引用获得class对象:将类装入内存(前提是:类还没有装入内存),不做类的初始化工作.返回Class的对象。