1 Object的内存结构和指针压缩了解一下
//hotspot的oop.hpp文件中class oopDesc
class oopDesc {
friend class VMStructs;
private:
volatile markOop _mark; //对象头部分
union _metadata { // klassOop 类元数据指针
Klass* _klass;
narrowKlass _compressed_klass;
} _metadata;
- Object的实例数据内存使用三部分组成的,对象头,实际数据区域、内存对齐区
- 对象头布局如下:主要和锁,hashcode,垃圾回收有关;由于锁机制的内容篇幅过长,这里就不多解释了;和锁相关的markWord(markOop)内存布局如下
2 Object的几种基本方法
- 本地方法
- private static native void registerNatives() 将Object定义的本地方法和java程序链接起来。Object类中的registerNatives
- public final native Class<?> getClass() 获取java的Class元数据
- public native int hashCode() 获取对象的哈希Code
- protected native Object clone() throws CloneNotSupportedException 获得对象的克隆对象,浅复制
- public final native void notify() 唤醒等待对象锁waitSet队列中的一个线程
- public final native void notifyAll() 类似notify(),唤醒等待对象锁waitSet队列中的全部线程
- public final native void wait(long timeout) 释放对象锁,进入对象锁的waitSet队列
- 普通方法
public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode());}
public boolean equals(Object obj) { return (this == obj);}
public final void wait(long timeout, int nanos) throws InterruptedException;
//都是基于native void wait(long timeout)实现的
public final void wait() throws InterruptedException;
wait(long timeout, int nanos)、wait()
//jvm回收对象前,会特意调用此方法
protected void finalize() throws Throwable;
Object的equals和hashCode
equals是用来比较两个对象是否相等的,可以重写该方法来实现自定义的比较方法;而hashCode则是用来获取对象的哈希值,也可以重写该方法。当对象存储在Map时,是首先利用Object.hashCode判断是否映射在同一位置,若在同一映射位,则再使用equals比较两个对象是否相同。
equals一样,hashCode不一样有什么问题?
如果重写equals导致对象比较相同而hashCode不一样,是违反JDK规范的;而且当用HashMap存储时,可能会存在多个我们自定义认为相同的对象,这样会为我们代码逻辑埋下坑。
Object.wait和Thread.sheep
Object.wait是需要在synchronized修饰的代码内使用,会让出CPU,并放弃对对象锁的持有状态。而Thread.sleep则简单的挂起,让出CPU,没有释放任何锁资源
finalize方法的使用
如果对象重写了finalize方法,jvm会把当前对象注册到FinalizerThread的ReferenceQueue队列中。对象没有其他强引用被当垃圾回收时,jvm会判断ReferenceQueue存在该对象,则暂时不回收。之后FinalizerThread(独立于垃圾回收线程)从ReferenceQueue取出该对象,执行自定义的finalize方法,结束之后并从队列移除该对象,以便被下次垃圾回收finalize会造成对象延后回收,可能导致内存溢出,慎用finally和finalize区别
finally是java关键字,用来处理异常的,和try搭配使用如果在finally之前return,finally的代码块会执行吗? try内的continue,break,return都不能绕过finally代码块的执行,try结束之后finally是一定会被执行的 相似的关键字final
final修饰类,该类不能被继承;修饰方法,方法不能被重写;修饰变量,变量不能指向新的值;修饰数组,数组引用不能指向新数组,但是数组元素可以更改如果对象被final修饰,变量有哪几种声明赋值方式?fianl修饰普通变量:1、定义时声明 2、类内代码块声明 3、构造器声明fianl修饰静态变量:1、定义时声明 2、类内静态代码块声明