Student stu = new Student();
请阐述 stu 找到 Student实例的 方式
答:两种方式,句柄和直接指针方式,句柄方式会创建句柄池,这样可以保证稳定的被访问到对象的地址。直接访问速度快,能节省定位指针的开销,但是数量大了也会影响开销。
请简述Student 对象在jvm中的分布
答:分为三个部分:
1.对象头(中间保存着Markword和类型指针):第一部分:用于存储对象自身的运行时数据, 如哈希码(HashCode) 、 GC分代年龄、 锁状态标志、 线程持有的锁、 偏向线程ID、 偏向时间戳等。第二部分就是通过这个指针定位到是哪一个类的实例
2.实例数据:对象所需要的属性数据,真正的有效信息
3.对齐填充:由于对象的大小必须是8bit的整数倍,所以不够的进行填充到整数倍。
请阐述jvm 是采用何种方式为Student 实例分配空间
答:两种方式:
1.指针碰撞:用过的在一侧,没用过的在另一侧,通过中间的指针向后移动相应的空间操作简单,要求空间一定是规整的,多线程下效率不高
2.空闲列表:需要一个列表里面多个对象空间,在表空间上做个记录,记录每块空间使用情况,对导致空间碎片问题
请简述jvm运行时数据区域 是如何划分的
答:
1.方法区:类的所有信息(方法,属性等)
static类型的类进入方法区之后会在方法区开辟属于自己的空间,所以静态的可以直接被调用,而非静态的不能直接被调用
2.栈区:运行时的单位
栈中存的是基本数据类型和堆中对象的引用,方法执行时可以从方法区中获取方法的副本生成栈帧进行压栈出栈。
3.程序计数器
线程私有的,是一块很小的内存空间,作为当前线程所执行的字节码的行号指示器,用于记录当前虚拟机正在执行的线程指令地址(下一次时间片到了之后又可以取指令再次执行)
4.堆区:存储的单位
存放创建的对象(分配了内存地址)
5.本地方法区:保存着本地方法
请简述如何判定一个对象的生死
答:两种方法
1.引用计数法:简单快速
引入一个对象计数器,对象使用就+1,如果不使用了-1,如果等于0之后就判断死亡
2.可达性分析:
这个算法的基本思路就是通过一系列称为“GC Roots”的根对象作为起始节点集,从这些节点开始,根据引用关系向下搜索,搜索过程所走过的路径称为“引用链”(Reference Chain),如果某个对象到GC Roots间没有任何引用链相连,或者用图论的话来说就是从GC Roots到这个对象不可达时,则证明此对象是不可能再被使用的。
请阐述你对java中引用的认识
1.强引用
在代码中普遍存在的 例如Object obj = new Object(),只要该引用还在就永远不会被回收
2.软引用
对于有点用但非必须的对象,当将要发生内存溢出之前,将会把这些对象列进回收范围中,并进行第二次回收。
3.弱引用
对于非必须对象的,但是只能存活到下一次回收之前,就是无论当前内存是否足够,都会对其进行回收。
4.虚引用
一个对象是否有虚引用的存在完全不会对其生存时间构成影响,也无法通过虚引用来获得一个实例,为一个对象设置虚引用的关联的唯一目的就是希望在这个对象被回收的时候可以收到一个系统通知。
请简述jvm垃圾回收算法
答:1.标记-清除算法:标记需要清楚的对象,再清除
算法分为“标记”和“清除”两个阶段: 首先标记出所有需要回收的对象, 在标记完成后, 统一回收掉所有被标记的对象, 也可以反过来, 标记存活的对象, 统一回收所有未被标记的对象。 标记过程就是对象是否属于垃圾的判定过程
缺点:空间碎片化,一个是执行效率不稳定
2.标记-复制算法:
它将可用内存按容量划分为大小相等的两块, 每次只使用其中的一块。 当这一块的内存用完了, 就将还存活着的对象复制到另外一块上面, 然后再把已使用过的内存空间一次清理掉
缺点:可用内存缩小为了原来的一半
3.标记-整理算法:
其中的标记过程仍然与“标记-清除”算法一样, 但后续步骤不是直接对可回收对象进行清理, 而是让所有存活的对象都向内存空间一端移动, 然后直接清理掉边界以外的内存
请阐述jvm中内存分配策略
答:大多数情况,对于新生对象先分配到Eden区(80%),空间不够的时候进行Minor GC。 对于大对象(比如字符串很长的数据对象)直接分配到老年区域。长期存活的对象将进入老年代 (Survivor区中每经历一次Minor GC没有被回收, 年龄就增加1岁, 当它的年龄增加到一定程度(默认为15) , 就会被晋升到老年代中)
请阐述你对synchronized的认识
答:synchronized是多线程并发编程中的同步锁,1.6之前是重量级锁,之后进行了优化并引出了偏向锁和轻量级锁和所得升级过程。
有三种锁的范围:
1.同步(锁住)普通方法---锁是当前实例对象(锁实例对象)
2.对于静态方法---锁是整个程序,也就是Class对象(锁住类)
3.对于同步方法块,锁是Synchonized括号里配置的对象。
请阐述你对volatile的认识
答:volatile是轻量级的"synchronized",达不到锁的程度,可见性,但是没有原子性保障---不会增加线程的上下文切换和调度
可以保证指令重排序和多线程下的可见性(通过内存屏障实现,可实现多线程中每个线程都能读到更新后的正确数据)
请写出两种单例模式 懒汉&&饿汉
1.懒汉式:在需要对象的时候才创建
private volatile static Singleton instance;//静态对象句柄 private Singleton() {}//私有构造器 public static Singleton getInstance() { //调用时才实例化对象,懒汉式 if(instance == null) { synchronized(Singleton.class){ if(instance == null){ instance = new Singleton(); } } } return instance; }
2.饿汉式:一开始就创建好对象
//私有化构造器 private Singleton() { } //内部创建对象实例 private final static Singleton instance = new Singleton();//饿汉式是提前创建好对象 //对外公有的静态方法 public static Singleton getInstance() { return instance; }