- 什么时候
从字面上翻译过来就是什么时候触发我们的GC机制
①在程序空闲的时候。这个回答无力吐槽
②程序不可预知的时候/手动调用system.gc()。关于手动调用不推荐
③Java堆内存不足时,GC会被调用。当应用线程在运行,并在运行过程中创建新对象,若这时内存空间不足,JVM就会强制地调用GC线程,以便回收内存用于新的分配。若GC一次之后仍不能满足内存分配的要求,JVM会再进行两次GC作进一步的尝试,若仍无法满足要求,则 JVM将报“out of memory”的错误,Java应用将停止。就是
这时候如果你们讲出新生代和老年代的话或许会更细的了解一下Minor GC、Full GC、OOM什么时候触发!
创建对象是新生代的Eden空间调用Minor GC;当升到老年代的对象大于老年代剩余空间Full GC;GC与非GC时间耗时超过了GCTimeRatio的限制引发OOM。
- 什么东西
从字面的意思翻译过来就是能被GC回收的对象都有哪些特征
①超出作用域的对象/引用计数为空的对象。
引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器就加1;当引用失效时,计数器值就减1;任何时刻计数器都为0的对象就是不可能再被使用的。
②从GC Root开始搜索,且搜索不到的对象
跟搜索算法:以一系列名为 GC Root的对象作为起点,从这些节点开始往下搜索,搜索走过的路径称为引用链,当一个对象到GC Roots没有任何引用链的时候,则就证明此对象是不可用的。
这里会提出一个思考,什么样的对象能成为GC Root : 虚拟机中的引用的对象、方法区中的类静态属性引用的对象、方法区中常量引用的对象、本地方法栈中jni的引用对象。
③从root搜索不到,而且经过第一次标记、清理后,仍然没有复活的对象。
- 做什么
不同年代、不同种类的收集器很多,不过总体的作用是删除不使用的对象,腾出内存空间。补充一些诸如停止其他线程执行、运行finalize等的说明。
ok 现在来回答一下我们最上面的问题,上面时候容易发生内存泄露
①静态集合类像HashMap、Vector等
②各种连接,数据库连接,网络连接,IO连接等没有显示调用close关闭,不被GC回收导致内存泄露。
③监听器的使用,在释放对象的同时没有相应删除监听器的时候也可能导致内存泄露。