System.gc()
1.默认情况下,通过System.gc()或者Runtime.getRuntime().gc()的调用,会显式触发Full GC,同时对老年代和新生代进行回收,尝试释放被丢弃对象占用的内存。
这俩方法相同
2.System.gc()Runtime.getRuntime().gc()/调用附带一个免责声明,无法保证对垃圾收集器的调用(提醒JVM的垃圾回收器执行GC但是不一定会执行)
3.JVM实现者可以通过System.gc()调用来决定JVM的GC行为。而一般情况下,垃圾回收应该是自动进行的,无需手动触发,否则就太过于麻烦了。在一些特殊情况下,如我们正在编写一个性能基准,我们可以在运行之间调用System.gc()
内存溢出(OOM)
没有空闲内存,并且垃圾收集器也无法提供更多内存。
除了程序计数器外,其他运行时数据区的部分都可能OOM
内存泄露(Memory Leak)
严格来说:对象不会再被程序用到了,但是GC又不能把他回收,就叫做内存泄漏。
宽泛来说:因为设计不当,导致某些对象生命周期过长,导致不能及时回收
例子:
1.把应该声明为局部变量的对象声明为类变量
2.在Web应用中,错把一些对象设置成会话范围。
3.某些对象已经不用了,但是忘记把他们之间的链接断开了。
4.单例对象引用了外部对象。因为单例对象的声明周期一般都是很长的,导致他引用的对象的声明周期也很长。
5.一些外部资源的连接对象没有及时关闭(close方法)如数据库连接 网络连接 io等
STW(Stop The World)
STW时,整个应用程序线程都会被暂停。
可达性分析算法中枚举根节点会导致STW
STW时间与采用那款GC无关,所有的GC都有这个事件。开发中不要用System.gc()会导致STW发生。STW是JVM在后台自动发起和自动完成的。
垃圾回收的并发与并行
并行:指多条垃圾收集线程并行工作,此时用户线程仍处于等待状态
如 ParNew 、Parallel、 Scavenge 、Parallel Old
串行:单线程执行回收完再启动程序线程
如 Serial 、Serial Old
并发:用户线程和垃圾回收线程在同一时间段内同时进行