在java中,内存管理包括两个方面: 内存分配(创建java对象)和 内存回收。这两个方面都是由jvm自动完成的。
java在内存中的状态先看以下代码
把上面对象引用图画成一个从 main方法开始的对象引用图就是这样的:

当程序运行起来后,把它的内存看成有向图,可以分为三种:
在一个对象创建之后,有一个以上的引用变量引用它。在有向图中可以从起始点到该对象。
可恢复状态如果程序中某个对象不再有任何的引用变量引用它(曾经有),他就可以先进入 可恢复状态,此时有向图是不能到达他的。
在这个状态下,系统的垃圾回收机制准备回收该对象所占用的内存。在回收前,系统会调用 finalize()进行资源清理。
如果资源清理后,有一个以上的引用变量 重新引用该对象,则其变回 可达状态,反正就进入**不可达状态**。
当对象的所有联系都被切断,且系统调用finalize()方法对资源进行清理后,仍旧没有引用对象引用,则变成 不可达对象,这时系统就会真正地去回收该对象。
一图表达:

创建一个对象,并把该对象直接复制给一个变量,如 Person person = new Person("sunny");。
不管系统资源多么紧张,都不会回收。
软引用是通过 SoftReference类实现的,如 SoftReference<Person> person = new SoftReference<Peson>( new Person("rain"))。
内存非常紧张时,会对其进行回收,其他时候则不会回收,所以在使用之前要进行null判断再使用。
弱引用是通过 WeakReference类实现的,如 WeakReference<Person> p = new WeakReference<Person>( new Person("rain") );
不管内存够不够,在进行垃圾回收时,都会进行回收。
不能单独引用,主要是用于追踪对象被垃圾回收的状态,通过 PhantomReference类和引用队列 ReferenceQueue类联合使用实现。
垃圾回收机制java垃圾回收主要做两件事, 内存回收和 碎片整理 。
垃圾回收算法串行回收和并行回收串行回收是不管系统有多少个cpu,都只用一个cpu来执行垃圾回收操作。
并行回收是把整个回收拆分成多个部分,每个部分由一个cpu负责,从而让多个cpu并行回收。
并行回收执行效率高,但是复杂度也高。
应用程序停止(Stop-the-world):其垃圾回收时,会导致程序暂停。
并发执行的垃圾回收虽然不会导致应用程序的暂停,但由于并发执行垃圾需要解决和应用程序的执行冲突,因此开销大,而且需要更多的堆内存。
支持压缩的垃圾回收器(标记-压缩 = 标记清除+压缩):会把所有的可达对象搬迁在一齐,然后将之前占用的内存全部回收,减少碎片。
不压缩的垃圾回收器(标记-清除):要遍历两次,第一先从根开始访问所有可达对象,并标记他们为可达状态;第二次便利用整个内存区域,对未标记可达状态的对象进行回收处理。
这种方式,不压缩,不需要额外内存,但要遍历两次。 (跟js的垃圾回收方式有点像)
复制式的垃圾回收器
将堆内存分成两个相同的空间,从根开始访问每一个关联的可达对象,将空间A的全部可达对象复制到空间B,然后一次性回收空间A。
| 欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) | 黑马程序员IT技术论坛 X3.2 |