面试题:java垃圾回收的命令是什么及其执行过程
首先:java内存是怎样分配的,对象是在5个地方存储数据
1.寄存器 java不能操作寄存器,汇编语言可以直接操作寄存器,可以忽略器存在;
2.堆栈 位于RAM(随机访问存储器)中,对象的引用存于堆栈中,其他语言例如c++,对象存于堆栈中
3.堆位于RAM(随机访问存储器)中,对象存于堆中
4.常量存储位于RAM(随机访问存储器)中,常量存放于此,例如:字符串常量
5.非RAM存储 持久化存储放于此,就是硬盘
Java语言最大的特点相对于C++,就是没有析构函数,所以垃圾回收不等于析构函数,概念完全不同。“永远不要销毁对象”,销毁对象的工作由JVM完成。
为什么不要手动调用垃圾回收期system.gc(),因为垃圾回收器工作时代价是昂贵的。当程序濒临存储空间用完的时刻垃圾回收才执行
全称“自适应的、分代的、停止-复制、标记-清扫”式垃圾回收器
1.“停止-复制” 依据的思路是从堆栈和静态存储区出发,遍历所有的引用,进而找出所有的存活对象。只有全部标记工作完成的时候,清理工作才开始。这种垃圾回收动作不是在后台进行的,相反,垃圾回收动作发生的同时,程序将会被暂停。
2.“标记-清扫” 在清理工作中。没有标记的对象将被释放。不会发生任何复制动作,所以剩下的堆空间是不连续的,垃圾回收器要是希望得到连续空间的话,就得重新整理剩下的对象。(用于没有垃圾产生的或少量垃圾时)
Java的工作原理特点:存储空间的释放会影响存储空间的分配。
class Book {
boolean checkedOut = false;
Book(boolean checkedOut){
this.checkedOut = checkedOut;
}
void checkIn() {
checkedOut = false;
}
@Override
protected void finalize() {
if(checkedOut) {
System.out.println("Error: checkede out");
}
}
}
class TerminatinonCodition {
public static void main(String[] args) {
Book novel = new Book(true);
novel.checkIn();
new Book(true);
System.gc();
}
}
注意:1.system.gc()用于强制进行终结动作(但是也不一定马上执行)。终结函数无法预料,常是危险的,总之是多余的。
2.本例是finalize的用法,主要是发现程序的隐形缺陷。本例的终结条件:所有Book对象在被当做垃圾回收前都应该被签入(check in),但是由于程序的错误,有一本书未被签入,要是没有finalize()来验证终结条件,将很难发现这种错误。
Finalize()特点:
一旦垃圾回收器准备工作,将优先调用Finalize()方法
1.对象可能不被垃圾回收 你写了Finalize()并不一定执行
2.垃圾回收并不等于“析构”
3.垃圾回收只与内存有关 垃圾回收器唯一原因是为了回收程序不再使用的内存。与内存没有关系的方法,自己写让程序调用,不要依赖Finalize()
Finalize()设计主要是来解决java调用其他语言如C++,造成内存泄漏的问题。Java自己对象是new的JVN自动管理。