轻松理解Java垃圾回收

来源:互联网 发布:知所然又知其所以然 编辑:程序博客网 时间:2024/06/07 15:43

垃圾回收的概念:

jvm中,堆内存和垃圾回收器这两个部分和垃圾回收相关。堆内存是运行时用来存储实例对象和数据的空间。垃圾回收只运行在堆区上。

 

在堆区和对象空间,把对象根据存活的周期,把对象分成3部分。

1. 年轻代

2. 老年代

3. 永久代

对象被回收的规则:当一个对象不被引用了,那么它就是可以被回收的对象。public static void main(String[]args) {

String s1="a";//"a"s1所依赖,s1被栈区所依赖

String s2="b";//s1已经从栈区弹出,这时"a"已经无人引用,"a"已经可以被回收

String s3="c";

}

eden

s0

s1

tenured

permanent

年轻区

老年区

永久区

年轻区:

Eden:所有的实例运行时最初的部分会分配到eden区。

S0eden区中经过一次垃圾回收之后依然存活的对象,会被转移到s0

S1s0区中再经过一次垃圾回收之后依然存活的对象,会被转移到s1区,如果s0满了,s1区也会转存一部分s0区的对象

老年区:s0s1几轮迭代后依然存活的对象。

永久区:元数据,方法等等(jdk1.8中已经移除了永久区)

 

垃圾回收机制:

Java的垃圾回收是一个自动运行的管理程序,通过gc的自动执行,jvm将程序员从申请和释放内存的繁重操作中解放出来。

 

GC是一个自动执行的进程,程序员不需要在代码中主动初始化gcJava提供了System.gc

()方法请求jvm调用gc

 

GC提供给程序员调用gc的机会。但是,jvm在执行这条命令的时候,它只会把这条命令当作是一个建议。因此手动调用gc不能保证这些请求会真的执行垃圾回收。Jvm会根据对内存中的eden区的实际使用情况,做出决定。

Jvm的规范把执行的选择权留给了各个版本的jvm的具体实现。

 

垃圾回收的流程:

1. 对象存放到eden区。

2. 如果对象没有被回收,会放到s区。

3. 如果对象在s区依然存活,则会放到t区。

4. t区,对象失去引用,则最后会被回收。

 

垃圾回收机制的各个区的详解:

Eden区:一个对象被创建的时候,它最初是被存放在堆内存的年轻代的eden区中。

S区(s0s1):eden区中的对象被回收过几轮之后,还存活的部分,会被从eden区转移到s0区。S0的对象回收过几轮之后,会被转移到s1区。

无用的对象会被立刻被打上标记,垃圾回收会根据标记来决定对象是继续留在原地,还是被转移到其他区或者是被回收。

O:老年代或者永久区的对象遵循的是另一套逻辑。当gc扫描年轻代区域的时候,s1区中的还活着的对象会被放到O区中。S1区中没有被应用的对象,会被立即删除。

Mayor GC:在java垃圾回收的最后一个阶段,如果发现对象没有任何引用,对象会被立即删除。

 

从上可以看出,生存周期越长的对象,被gc扫描的频率就越低。

碎片的概念:

一旦实例在堆区中被删除,它们原来的位置就空出来以供后面的对象使用。但是这些闲暇空间的操作,必然会产生很多空隙,这些空隙就是内存碎片。

为了更快更有效率的重新利用内存,就需要对内存做去碎片化操作,此操作是由GC完成。根据不同的GC的策略,被回收的内存会被独立的内存压缩程序所整合。

 

Java中提供了4种垃圾回收器:

1. Serial Garbage Collector:顺序回收

2. Parallel Garbage Collector:并行回收

3. CMS Garbage Collector:并发标记回收

4. G1 Garbage Collector:网格化回收

 

Serial Garbage Collector:它是为但线程场景设计,只使用一个线程。它启动的时候会暂停所有应用线程。它适合简单的命令行程序。

使用-XX:+UseSerialGC参数

 

Parallel Garbage Collector:并发多线程垃圾回收器。它是jvm的默认回收器。与Serial不同的是,它是使用多个线程来执行垃圾回收工作。它在执行垃圾回收的时候,也是需要暂停所有应用线程。

 

CMS Garbage Collector:并发标记回收(concurrent mark sweep),使用多个线程扫描对内存标记可以被回收的对象,清除标记对象。

CMS只在两种情况下需要暂停应用线程:

1. 在老年区中标记引用对象的时候

2. 在做垃圾回收的时候,堆内存有变化

CMS比其他两种gc拥有更高的并发吞吐量,CMS需要占用更高的CPU性能。

使用-XX:+UsePalNewGC参数

 

G1 Garbage CollectorG1垃圾回收器适用于更大的堆内存。它将内存划分成不同的区块,对各个区块分别进行回收工作。G1在回收空间之后会会立刻对堆空间的空闲空间进行整合。CMS也有内存整合,但需要停止所有线程后执行内存整合工作(STWstop the

world)。而G1可以对不同的区间根据优先级进行整合。

使用-XX:+UseG1GC参数

 

JVM的优化参数:

 

1.-Xms:设置堆区的初始大小

2.-Xmx: 设置堆区的最大值

3.-Xmn: 设置年轻代的大小

4.-XX:PermSize:设置永久代的初始大小

5.-XX:MaxPermSize:设置永久代的最大值

JVM参数实例:

java –Xms10m –Xmx100m –Xmn1m -XX:PermSize20m -XX:MaxPermSize20m -XX:+UseSerialGC JavaApp

 

java的垃圾判断和回收托管的特征:

GC什么时候会回收一个对象呢?

1. 对象没有引用

2. 作用域发生了未被捕获的异常

3. 程序在作用域正常结束

4. 程序运行了System.exit(0);

5. 程序意外终止(被杀进程等等)

 

Jvm的内存泄漏:

1. 循环引用(1.2之后就被解决了)

2. 调用对象和被调用对象的生命周期不一致(良好的编程习惯)

3. gc在执行回收操作的时候发生异常,这个异常往往是重写finalize方法引发的。

原创粉丝点击