一.jvm内存模型:
1. Java栈: 逻辑单位,存储对象引用,变量值,基本数据类型(长度固定)
2. Java堆: 年轻代(伊甸区/幸存区1/幸存区2),老年代(可变对象长度),8的整数倍byte。
1) full gc整个堆扫
2) minor gc只是年轻代
3) 因为大部分对象都是从Eden区开始的,同时Eden区不会分配的很大,所以Eden区的GC会频繁进行。因而,一般在这里需要使用速度快、效率高的算法,使Eden去能尽快空闲出来。
4)年老代有一个"card table",记录年老代指向新生代的对象引用。新生代回收时只需要查询年老代该table就可以。加快速度
5) 大对象,长期存活的对象进入老年代
3. 方法区: 静态变量,常量(字符串)
二.基本回收算法:
按策略:
1.引用计数: 有引用加一,删除引用减一。回收引用为0的对象。无法回收循环引用对象
2.复制: 需要两倍空间,一个满了将正在使用的对象复制到另一个空间。不会出现碎片问题
3.标记清除: 首先由根节点开始,标记被引用对象,然后回收未被引用的。会暂停以及产生内存碎片
4.标记清理: 首先由根节点标记所有被引用对象。然后清除未标记对象,并压缩在一起
按线程:
1.串行: 单CPU
2.并行: 多线程收集,需要暂停运行环境。堆空间大的时候,回收的时间也变长。适用于对吞吐量有要求的。比如后台计算程序
-XX:+UseParallelGC.打开。
-XX:ParallelGCThreads=<N>设置并行垃圾回收的线程数。此值可以设置与机器处理器数量相等。
-XX:MaxGCPauseMillis=<N>指定。<N>为毫秒.如果指定了此值的话,堆大小和垃圾回收相关参数会进行调整以达到指定值。设定此值可能会减少应用的吞吐量。
吞吐量:吞吐量为垃圾回收时间与非垃圾回收时间的比值,通过 -XX:GCTimeRatio=<N>来设定,公式为1/(1+N)。
3.并发: 不停顿。可以保证大部分工作都并发进行(应用不停止)。会产生浮动垃圾,必须要清理完之前保证老年代没有满。对响应时间有要求的。Web服务器
XX:+UseConcMarkSweepGC打开。
-XX:CMSInitiatingOccupancyFraction=<N>指定还有多少剩余堆时开始执行并发收集。并发收集器一般需要20%的预留空间用于这些浮动垃圾。
三. 内存泄漏几种情况:
1. Java heap space: 年老代满了。找到回收后残余对象,然后分析
2. PermGen space: 持久代满了。 Java大量反射导致class文件太多
四.常用调优参数:
1) -xx:NewRatio: 指定新生代和老年代大小比例.基本上是新:老=1:2=3:8
2)
五. 查询命令:
1. dump内存快照 /usr/java/jdk1.6.0_29/bin/./jmap -dump:format=b,file=/dev/shm/dump.bin -F 18188
2. 查看堆内存对象数量,大小: jmap -histo pid
3. 查看堆使用情况: jmap -heap pid
4. 打印给定进程id 的堆栈信息: jstack [ option ] pid
5. 发现死锁: jstack -l pid 两个线程互相locked而且等待对方的某个资源(号一样)