本地方法栈中的对象
(5)MinorGC和Full GC:
新生代GC(Minor GC):指发生在新生代的垃圾收集动作,因为 Java 对象大多都具备朝生 夕灭的特性,所以 Minor GC 非常频繁,一般回收速度也比较快。
老年代GC(Full GC):是清理整个堆空间—包括年轻代和老年代或者永久代。。Full GC 的速度一般会比 Minor GC 慢 10 倍以上。
四、垃圾回收算法:
(1)标记-清除算法:

“标记-清除”(Mark-Sweep)算法,算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收掉所有被标记的对象。
缺点:
- 一个是效率问题,标记和清除过程的效率都不高;
- 一个是空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能 会导致,当程序在以后的运行过程中需要分配较大对象时无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。
(2)复制算法:

复制”(Copying)的收集算法,它将可用内存按容量划分为大小相等的两块,每次只使用 其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。
缺点:
- 这种算法的代价 是将内存缩小为原来的一半,持续复制长生存期的对象则导致效率降低。
(3)标记整理算法:

标记-整理”(Mark-Compact)算法,标记过程仍 然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。
(4)分代收集算法:
分代收集”(Generational Collection)算法,把 Java 堆分为新生代和老年代,这样就可以 根据各个年代的特点采用最适当的收集算法。
年轻代(生存周期短,大量对象都是垃圾对象) 使用复制算法。
年老代(生存周期长,少量对象时垃圾对象) 使用标记整理,或者标记清除。
五、垃圾收集器:
如果说垃圾收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现。不同厂商、不 同版本的虚拟机实现差别很大,HotSpot 中包含的收集器如下:

(1)Serial 收集器(单核服务器,最快,单线程版本):
串行收集器是最古老,最稳定以及效率高的收集器,可能会产生较长的停顿,只使用一个线 程去回收。新生代、老年代使用串行回收;新生代复制算法、老年代标记-压缩;垃圾收集 的过程中会 Stop The World(服务暂停)

这种算法的缺点就是:在垃圾回收的时候,会停止其他的线程
(2)ParNew收集器(多线程版本)
ParNew 收集器其实就是 Serial 收集器的多线程版本。
新生代并行,老年代串行;新生代复制算法、老年代标记-整理

(3)Parallel收集器(多线程)
Parallel Scavenge 收集器类似 ParNew 收集器,Parallel 关注吞吐量的多线程 ParNew 进化版。新生代复制算法、老年代标记-整理算法。

(4)CMS收集器(多线程)
CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。目 前很大一部分的 Java 应用都集中在互联网站或 B/S 系统的服务端上,这类应用尤其重视服务的响应速度,希望系统停顿时间最短,以给用户带来较好的体验。

优点:并发收集、低停顿
缺点:产生大量的空间碎片,并发节点吞吐率低。
参数配置:
-XX:+UseConcMarkSweepGC 使用 CMS 收集器
-XX:+ UseCMSCompactAtFullCollection Full GC 后,进行一次碎片整理;整理过程是独占的,会引起停顿时间变长
-XX:+CMSFullGCsBeforeCompaction 设置进行几次 Full GC 后,进行一次碎片整理
-XX:ParallelCMSThreads 设定 CMS 的线程数量(一般情况约等于可用 CPU 数量)
(5)G1收集器(多线程)
特点:
- 空间整合:G1 收集器采用标记整理算法,不会产生内存空间碎片。分配大对象时不会因为无法找到连续空间而提前触发下一次 GC。
- 可预测的停顿:,降低停顿时间是 G1 和 CMS 的共同关注点,但 G1 除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为 N 毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒,这几乎已经是实时Java(RTSJ) 的垃圾收集器的特征了。
- G1搜集器,Java 堆的内存布局与其他收集器有很大差别,它将整个 Java 堆划分为多个大 小相等的独立区域(Region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔阂了,它们都是一部分(可以不连续)Region 的集合。

G1 的新生代收集跟 ParNew 类似,当新生代占用达到一定比例的时候,开始触发收集。这样一来可以做到,当达到一定的比例时,触发垃圾回收,那些没有使用region仍然可以对外提供使用,就有效的避免了stop the world。
与CMS的比较:
- 分代:CMS 中,堆被分为 PermGen,YoungGen,OldGen;而 YoungGen 又分了两个 survivor 区域。在 G1 中,堆被平均分成几个区域(region),在每个区域中,虽然也保留了新老代的概 念,但是收集器是以整个区域为单位收集的。
- 算法:相对于 CMS 的“标记—清除”算法,G1 会使用“标记--整理”算法,保证不产生 多余的碎片。
- 停顿时间可控制:了缩短停顿时间,G1 建立可预存停顿模型,这样在用户设置的停顿时 间范围内,G1 会选择适当的区域进行收集,确保停顿时间不超过用户指定时间。
六、jvm参数配置以及常用的分析工具:
(1)jvm的参数列表:
各个内存大小分配:
java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=16m -XX:MaxTenuringThreshold=0
-Xmx3550m:最大堆内存为 3550M
-Xms3550m:初始堆内存为 3550m
一般情况:-Xmx与-Xms值设置为相同的,以避免每次垃圾回收完成后 JVM 重新分配内存。
-Xmn2g:设置年轻代大小为 2G
-Xss1m:设置每个线程的堆栈大小
-XX:NewRatio=4:设置年轻代(包括 Eden 和两个 Survivor 区)与年老代的比值(除去持久 代)。设置为 4,则年轻代与年老代所占比值为 4:1,年轻代占整个堆栈的 4/5
-XX:SurvivorRatio=4:设置年轻代中 Eden 区与 Survivor 区的大小比值。
-XX:MaxPermSize=16m:设置持久代大小为 16m。
-XX:MaxTenuringThreshold=15:设置垃圾最大年龄。
收集器设置:
-XX:+UseSerialGC 设置串行收集器
-XX:+UseParallelGC 设置并行收集器
-XX:+UseParalledlOldGC 设置并行年老代收集器
-XX:+UseConcMarkSweepGC 设置并发收集器
垃圾回收统计信息:
-XX:+PrintGC
–XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-Xloggc:filename
并行收集器设置:
-XX:ParallelGCThreads=n 设置并行收集器收集时使用的 CPU 数。并行收集线程数
-XX:MaxGCPauseMillis=n 设置并行收集最大暂停时间
-XX:GCTimeRatio=n 设置垃圾回收时间占程序运行时间的百分比。公式为 1/(1+n)
并发收集器设置:
-XX:+CMSIncrementalMode 设置为增量模式。适用于单 CPU 情况
-XX:ParallelGCThreads=n 设置并发收集器年轻代收集方式为并行收集时,使用的 CPU 数并行收集线程数
(2)jvm分析工具:
jps:查看java进程
-q 只显示pid,不显示class名称,jar文件名和传递给main 方法的参数
-m 输出传递给main 方法的参数,在嵌入式jvm上可能是null
-l 输出应用程序main class的完整package名 或者 应用程序的jar文件完整路径名
-v 输出传递给JVM的参数
jps host 查看host的jps情况(前提:host提供jstatd服务)
jstatd:启动jvm监控服务。它是一个基于rmi(远程接口调用)的应用,向远程机器提供本机jvm应用程序的信息。默认端口1099。-p指定端口。
jmap1:观察运行中的jvm物理内存的占用情况
-heap:打印jvm heap的情况(垃圾收集器类型)
-histo:打印jvm heap的直方图。其输出信息包括类名,对象数量,对象占用大小。
-histo:live :同上,但是只打印存活对象的情况
-permstat:打印permanent generation heap(方法区)情况
-finalizerinfo:打印正等候回收的对象信息
jmap2:用jmap把进程内存使用情况dump到文件中,再用jhat分析查看。
jmap -dump:format=b,file=dumpFileName pid
jmap -dump:format=b,file=4574.heap20151215 4574
jinfo:打印命令行参数和系统属性
-flags 打印命令行参数
-sysprops 打印系统属性
jstack1:能得到运行java程序的java stack和native stack的信息。可以轻松得知当前线程的运行情况
-l长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表
-m打印java和native c/c++框架的所有栈信息
jstat:
Options — 选项,我们一般使用 -gcutil /-gc 查看gc情况
pid — VM的进程号,即当前运行的java进程号
interval[s|ms] —— 间隔时间,单位为秒或者毫秒,默认为ms。必须是正整型
count — 打印次数,如果缺省则打印无数次
例:jstat -gc 4645 500 10 表示查看进程为4645的gc每个 500ms打印一次,一共打印10次