您的位置:首页 > 编程语言 > Java开发

JAVA内存与GC总结

2017-09-16 22:41 405 查看

首先列出内存结构

静态区

permspace(jdk<=1.7)

`线程共享,存储常量、静态变量、加载的类信息,由参数指定大小


metaspace(jdk>=1.8)

线程共享,替代permspace,常量信息移动到堆当中,虚拟机维护


栈区

JAVA栈

线程私有,当前调用栈的上下文、localcar、方法的成员变量等


本地方法栈(native)

线程私有,虚拟机或jni提供的本地方法的调用上下文


程序计数器

线程私有,存储当前线程行号、分支、循环、跳转、异常信息、同时存储线程状态切换等信息


堆区

JAVA堆

共享,存储java对象,等,分为多个空间


非堆区

非堆

程序自己控制的内存区域,可以由NIO的DiretByteBuffer或UNSAFE方法分配


JAVA垃圾回收原理

JAVA中由垃圾回收器负责的空间主要为堆与静态区,静态区在老FGC时均会被整理,且其也会触发FGC不再阐述

堆的结构

堆分为两个部分,新生代与老年代

新生代:JAVA对象在创建之初都存在于新生代(大对象除外),经过多次GC仍然存在的对象会被移动到老年代,由空间的连续性考虑,新生代的GC比较频繁,使用只复制法整理空间效率更高,但消耗更多的内存。所以堆在内部又再次划分为两个空间类型,Eden与Survivor,其中Survior内部再次划分为两个空间且一个时间只会使用其中一个,两个Survior空间在每次GC时交换身份。当GC被触发时,Eden中存活下来的对象将会移动到正在使用的Survivor当中,当此Survivor满时,则对其进行整理,仍然存活的对象会被复制到另外一个Survivor当中。

老年代:一个对象在Survivor中多次存活(次数可配),则会被移动到老年代。考虑到空间的使用,与被触发GC次数较少,使用内部整理的方式来处理连续性,降低了内存开销与复杂度。

堆的垃圾收集算法

1)复制算法:*只适用于新生代。内存拆分为两份,申请内存时只返回正在使用的那部分,这个空间称作Eden,另外一个称为Survivor,标记回收的对象后,将不需要回收的对象复制到Survivor空间。算法实现有:Serial(单线程);ParNew(多线程收集器);ParallelScavenge(吞吐量优化算法,自动调节策略降低停顿)

2)标记清除算法:*只适用于老年代。首先根据引用计数标记需要回收的对象,随后统一回收。会产生较多碎片,但性能最高。算法实现有:ConcurrentMarkSweep(CMS,并发清除算法,分三阶段执行,仅前两个阶段停顿,停顿最小,产生的碎片智能整理(需要时),也可以配置整理)

3)标记整理算法:*只适用于老年代,申请内存时,只采用一个方向的分配方式,则内存的另一端将不会被使用。之后在将不需要回收的对象向此端复制。算法实现有:SerialOld(单线程),ParallelOld(多线程)

4)分区整理算法:新型的内存结构,不再适用上文中的内存结构,它将JAVA堆内存分割为多个区域,每个区域都可以成为新生代或老年代的身份,当空间不足时便对这些分区分个进行整理,存活的对象复制到新的分区中,这样每次GC都不用对整个空间做整理,停顿非常少。算法实现:GarbageFirst(G1)

GC分析

JAVA当中的GC分为两种,Minor GC / Major GC(FGC)

…待整理

内存使用优化思路

合理使用非堆

非堆的性能优化点在于不在垃圾回收器的工作内容之中,合理使用降低垃圾回收器的负担,同时,非堆也优化了IO的操作,减少JAVA虚拟机内存向系统内存拷贝的环节,优化性能

集合的初始化大小

尽量指定集合的初始化大小,降低扩容次数

待整理。。。。。

GC优化思路

待整理。。。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 优化