一. 堆内存分配策略

我们都知道,java中对象都放在堆中,那么JVM会如何给新生对象分配内存呢?

内存参数回顾:-Xms初始堆内存大小,-Xmx最大堆内存,相等不可扩展,-Xmn堆中新生代对象的内存大小,剩余的就是老年代内存

有下面几个原则:

(1)优先使用Eden区域

新来的要分配内存的对象都属于新生代对象,我们知道,回收新生代对象是复制算法,,分为Eden区和两个survivor区,所以新生代对象首先在Eden中分配,当Eden内存不够,发起一次Minor GC(新生代GC),如果Minor GC执行完,还不够,就需要老年代区域担保分配,这里是把已经在的对象转移到老年代,要分配的新对象还是在会存在Eden

(2)大对象直接放入老年代

虚拟机提供参数-XX:PretenureSizeThreshold参数(这个参数只在serial和ParNew起作用),当对象比这个值大,就直接存入老年代

(3)长期存活的对象将进入老年代

虚拟机为每个新生对象设置一个年龄,当进行一次Minor GC时,会有对象被移到survivor2中,在survivor2中的对象没熬过一次Minor GC,年纪就会增加,直到超过参数-XX:MaxTenuringThreshold设置的阈值就会被移到老年代,这个阈值默认是15。

(4)动态判断对象年龄

并不是只有到了这个年纪对象的阈值才会被移到老年代,当survivor2中相同年纪的对象总数大于survivor2空间的一般,大于这个年纪和等于这个面积的对象都会被移到老年代中

(5)空间分配担保

前面说到了空间担保是指需要老年代担保,那么你必须判断,老年代中目前连续的内存空间是否大于当前survivor2中所有对象的大小,大于才能担保

所以在每一次Minor GC之前都会检查,如果大于则Minor GC认为是安全的。在jdk1.6之后,如果检查安全就进行Minor GC,否则进行full GC.。那么1.5之前是检查参数是否允许担保失败

二. 查看虚拟机状态与故障处理

JDK命令行工具可以监管虚拟机性能,让程序员了解虚拟机运行状态,对出现的故障进行修复

一般当虚拟机出现问题我们查看其运行日志,异常堆栈,GC日志,线程快照(threaddump),堆转储快照(heapdump)等

一般我们了解的jdk命令行工具就是jdk lib下的java.exe和javac.exe,其实bin目录下也有很多命令行工具主要是监视虚拟机和故障处理的

jps命令

查看虚拟机当前进程状况,列出正在运行的进程的唯一编号LVMID
4.JVM--堆内存分配策略

jstat命令

格式:jstat option vmid interval count

根据进程号LVMID查看当前进程运行情况,是运行期定位虚拟机性能的首选

(如果是本地进程LVMID和VMID是一样的)

option的选项 -gc 监视java堆的情况 -class 监视类装载,卸载数量,以及耗费时间 -gcutil 跟-gc差不多,主要产看各部分年代占空间比例
4.JVM--堆内存分配策略
每隔250毫秒产看进程25144的内存堆情况,检查20次

jinfo命令

4.JVM--堆内存分配策略

Java配置信息工具

格式

jinfo -flag 参数名 pid

产看JVM各种参数信息,区别于jps -v(查看虚拟机启动时的显示指定的参数列表),
4.JVM--堆内存分配策略
这个命令可以根据参数名称参看对应的值

jmap命令

内存映像工具,用于生产堆转储快照(heapdump),还可以查看finalize队列,java堆和永久代详细信息,如空间使用率和使用的哪种回收器

格式:

jmap option vimd

option=[-dump -finalizerinfo -heap -histo -F]

jhat命令

jhat与jmap搭配使用,jhat分析jmap生成的dump快照,是的可以在浏览器查看dump文件

jstack命令

堆栈跟踪工具,在并发中是比较有用的工具

该命令可以生成当前时刻线程的快照,线程快照就是当前虚拟机内每一条线程正在执行的方法的堆栈的集合,生成线程快照的目的是定位线程出现长时间停顿的原因(如是否发生死锁,死循环,请求外部资源时间过程中都可能造成线程长时间停顿)

格式 jstack option vmid

option=[-l 锁的信息-m 调用本地方法,显示c/c++堆栈]

当然在java.lang.Thread新增方法getAllStackTraces()方法可以实现jstack的大部分功能,但是命令行形式也容易使用

JDK的可视化工具

JConsole:控制台

VisualVM多合一故障处理工具

基于neatbean平台开发,具备插件扩展功能,可以完成上述命令行的所有功能 all in one,jdk1.6之后出现

相关文章: