Java语言是为数不多支持多线程技术的编程语言,而这多线程就不得不提到JVM虚拟机
先看代码案例:(JVM收垃圾)
package android.java.thread; class Demo { /** * 此方法是Object最终父类提供的方法 * 此方法可以获得当前Demo被JVM回收机制回收掉了 * @throws Throwable */ @Override protected void finalize() throws Throwable { // super.finalize(); System.out.println("Demo finalize 方法 我被JVM回收机制回收掉了!"); } } public class Test { public static void main(String[] args) { System.out.println("main 方法 开始执行"); new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟,由于此对象没有引用 这个匿名对象 会被JVM优先回收 // 调用回收机制来回收,调用了gc(); 会不会马上回收 这个不确定,这个是随机性的 System.gc(); System.out.println("main 方法 执行完毕!"); } }
日志打印结果:
第一次执行结果:
main 方法 开始执行
main 方法 执行完毕!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
第二次执行结果:
main 方法 开始执行
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
main 方法 执行完毕!
第三次执行结果:
main 方法 开始执行
main 方法 执行完毕!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
经过以上三次执行结果可以看出,每次JVM回收机制回收掉哪些Demo是不一样的,这个是JVM内部的随机性(应该说是内部的处理)
经过以上代码可以看出,至少有两个线程在跑:注意⚠️实际上有很多线程在跑,这是Java内部在处理的,但至少有以下两个线程在跑
1.main主线程,负责执行自定义代码;--> 线程1
2.JVM回收机制线程,负责回收垃圾;--->线程2
案例:(匿名对象 与 引用对象) 回收机制
package android.java.thread; class Demo2 { /** * 此方法是Object最终父类提供的方法 * 此方法可以获得当前Demo被JVM回收机制回收掉了 * @throws Throwable */ @Override protected void finalize() throws Throwable { // super.finalize(); System.out.println("Demo finalize 方法 我被JVM回收机制回收掉了!"); } } class Student { /** * 此方法是Object最终父类提供的方法 * 此方法可以获得当前Demo被JVM回收机制回收掉了 * @throws Throwable */ @Override protected void finalize() throws Throwable { // super.finalize(); System.out.println("Student finalize 方法 我被JVM回收机制回收掉了!"); } } public class Test2 { public static void main(String[] args) { System.out.println("main 方法 开始执行"); new Demo(); // 创建匿名对象,只在堆内存开辟空间,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟空间,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟空间,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟空间,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟空间,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟空间,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟空间,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟空间,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟空间,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟空间,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟空间,由于此对象没有引用 这个匿名对象 会被JVM优先回收 new Demo(); // 创建匿名对象,只在堆内存开辟空间,由于此对象没有引用 这个匿名对象 会被JVM优先回收 Student student1 = new Student(); // 创建引用对象,在栈内存/堆内存开辟空间,由于此对象有引用,JVM会检测后处理后才回收 Student student2 = new Student(); // 创建引用对象,在栈内存/堆内存开辟空间,由于此对象有引用,JVM会检测后处理后才回收 Student student3 = new Student(); // 创建引用对象,在栈内存/堆内存开辟空间,由于此对象有引用,JVM会检测后处理后才回收 Student student4 = new Student(); // 创建引用对象,在栈内存/堆内存开辟空间,由于此对象有引用,JVM会检测后处理后才回收 Student student5 = new Student(); // 创建引用对象,在栈内存/堆内存开辟空间,由于此对象有引用,JVM会检测后处理后才回收 Student student6 = new Student(); // 创建引用对象,在栈内存/堆内存开辟空间,由于此对象有引用,JVM会检测后处理后才回收 Student student7 = new Student(); // 创建引用对象,在栈内存/堆内存开辟空间,由于此对象有引用,JVM会检测后处理后才回收 Student student8 = new Student(); // 创建引用对象,在栈内存/堆内存开辟空间,由于此对象有引用,JVM会检测后处理后才回收 Student student9 = new Student(); // 创建引用对象,在栈内存/堆内存开辟空间,由于此对象有引用,JVM会检测后处理后才回收 Student student10 = new Student(); // 创建引用对象,在栈内存/堆内存开辟空间,由于此对象有引用,JVM会检测后处理后才回收 Student student11 = new Student(); // 创建引用对象,在栈内存/堆内存开辟空间,由于此对象有引用,JVM会检测后处理后才回收 Student student12 = new Student(); // 创建引用对象,在栈内存/堆内存开辟空间,由于此对象有引用,JVM会检测后处理后才回收 Student student13 = new Student(); // 创建引用对象,在栈内存/堆内存开辟空间,由于此对象有引用,JVM会检测后处理后才回收 Student student14 = new Student(); // 创建引用对象,在栈内存/堆内存开辟空间,由于此对象有引用,JVM会检测后处理后才回收 // 调用回收机制来回收,调用了gc(); 会不会马上回收 这个不确定,这个是随机性的 System.gc(); System.out.println("main 方法 执行完毕!"); } }
第一次执行结果:
main 方法 开始执行
main 方法 执行完毕!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
第二次执行结果:
main 方法 开始执行
main 方法 执行完毕!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
第三次执行结果:
main 方法 开始执行
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
main 方法 执行完毕!
第四次执行结果:
main 方法 开始执行
main 方法 执行完毕!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
第五次执行结果:
main 方法 开始执行
main 方法 执行完毕!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
第六次执行结果:
main 方法 开始执行
main 方法 执行完毕!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
Demo finalize 方法 我被JVM回收机制回收掉了!
.........
以上执行结果 执行了六次也没有出现,Student被回收,说明Student是引用对象,JVM回收机制回收优先级很低(JVM要做很多检测,来判断Student)