1. System.gc()的理解
通过 system.gc()或者 Runtime.getRuntime().gc() 的调用,会显式触发 Full GC,同时对老年代和新生代进行回收,尝试释放被丢弃对象占用的内存。
Runtime一个线程对应一个,Runtime相当于运行时数据区这样一个东西
2. 内存溢出与内存泄露
内存溢出(OOM):
- Java 虚拟机的
堆内存设置不够
。 - 代码中创建了大量
大对象
,并且长时间不能被垃圾收集器收集
(存在被引用)
内存泄漏(Memory Leak):对象不会再被程序用到了,但是 GC 又不能回收他们的情况
内存泄漏
并不会立刻引起程序崩溃,但是一旦发生内存泄漏,程序中的可用内存就会被逐步蚕食,直至耗尽所有内存
,最终出现 OOM
异常,导致程序崩溃。
-
单例模式
单例的生命周期和应用程序是一样长的,所以单例程序中,如果持有对外部对象的引用的话,那么这个外部对象是不能被回收的,则会导致内存泄漏的产生。
-
- 一些提供
close 的资源未关闭
导致内存泄漏
数据库连接(dataSourse.getConnection() ),网络连接(socket)和 io 连接必须手动 close,否则是不能被回收的。
- 一些提供
3. 垃圾回收的并行与并发
并行(Parallel)
指多条垃圾收集线程并行
工作,但此时用户线程仍处于等待状态。如 ParNew
、Parallel Scavenge
、Parallel Old
;
串行(Serial)
相较于并行的概念,单线程执行
。如果内存不够,则程序暂停,启动 垃圾回收器进行垃圾回收。回收完,再启动程序的线程。
并发(Concurrent)
指用户线程与垃圾收集线程同时执行(但不一定是并行的,可能会交替执行),垃圾回收线程在执行时不会停顿用户程序的运行。用户程序在继续运行
,而垃圾收集程序线程运行于另一个 CPU 上
;如:CMS
、G1
4. 对可达的对象的GC
4.1 强软弱虚引用
强引用——不回收,OOM也不回收
使用 new创建一个新的对象,并将其赋值给一个变量的时候,这个变量就成为指向该对象的一个强引用
。
软引用:内存不足才回收
只被软引用关联着的对象,在系统将要发生内存溢出异常前,会把这些对象列进回收范围之中进行第二次回收
,如果这次回收还没有足够的内存,才会抛出内存溢出异常
。
弱引用:只要发生GC,就回收
软引用、弱引用都非常适合来保存那些可有可无的缓存数据
。当系统内存不足时,这些缓存数据会被回收,不会导致内存溢出
。而当内存资源充足时,这些缓存数据又可以存在相当长的时间,从而起到加速系统的作用。
虚引用:对象回收的跟踪
-
能在这个对象被收集器回收时收到一个系统通知。
-
由于虚引用可以跟踪对象的回收时间,因此,也可以将一些资源释放操作放置在虚引用中执行和记录。