实战java虚拟机_实战JAVA虚拟机笔记

JVM结构

906e33ae4880bf45efdb4d12099e1d38.png

类加载子系统: 类加载子系统加载类后,将类信息放到方法区,除了类信息外还有运行时常量池信息

java堆: 堆在启动时建立,存放所有java实例,堆空间所有线程共享

直接内存: NIO会使用直接内存,读写频繁的场合会考虑使用直接内存

垃圾回收系统: 垃圾回收系统会对方法区,java堆和直接内存进行回收

java栈: 每个线程都会有一个java栈,启动线程就创建栈,栈保存局部变量,方法参数

本地方法栈: 本地方法栈用于本地方法调用

PC寄存器: 每个线程创建一个PC寄存器

新生代: eden区 S0区(from区) S1区(to区)

d06885a79ee12fc49c07b05131d0ebb1.png

对象先分配到eden区,在一次新生代后,如果对象还存活则进入S0或者S1区,每经过一次新生代回收,年龄就会加1,当年龄到一定程度后被认为是老年对象,进入老年代

SimpleHeap s1=new SimpleHeap(1);

SimpleHeap s2=new SimpleHeap(2);

7eb36528890e1a5a761dadc18e2723c9.png

-Xss 指定线程最大栈空间

局部变量表存在栈中,如果局部变量过多,每一次调用函数会占用更多的栈空间,最终导致嵌套可调用次数减少

jdk1.7前参数-XX:MaxPermSize 设置永久区的大小,jdk1.7之后使用-XX:MaxMetaspaceSize 设置元数据区的大小

常用JVM参数

-XX:+PringGC 只要遇到GC就会打印日志,打印详细信息:-XX:PringGCDetails

-XX:+PrintGCTimeStamps 输出GC发生时间

-XX:+PrintPrintGCApplicationConcurrentTime 打印应用程序执行时间

-XX:+PrintGCApplicationStoppedTime 打印应用程序由于GC产生的停顿时间

-XX:+PrintReferenceGC 跟踪软引用,弱引用,虚引用和FinaFinallize队列

-Xloggc:log/gc.log 打印日志到文件

堆参数设置

一般设置初始堆-Xms和最大堆-Xmx设置相等,有利于减少垃圾回收次数

-Xmn 设置新生代的大小,一般设置为整个堆空间的1/3或1/4

-XX:SurvivorRatio 设置新生代中Eden空间和from/to空间比例关系 eden/from=eden/to

-XX:SurvivorRatio设置后不生效:

原来,在HotSpot VM里,并行系的收集器(UseParallelGC / UseParallelOldGC)默认开启-XX:+UseAdaptiveSizePolicy, 这个配置会在每次Minor GC之后对From和To区进行自适应分配大小,而SurvivorRatio使用默认值8,设置成任何非8的数值都会无效。所以,我这个参数里面的-XX:+UseAdaptiveSizePolicy其实是画蛇添足了

垃圾回收算法

引用计数法, 标记压缩法, 标记清除法, 复制算法, 分代分区算法

新生代: 复制算法

老年代: 标记压缩算法,标记清除算法

软引用: GC未必会回收弱引用对象,当内存资源紧张的时候会回收

弱引用: GC每次发现都会回收

虚引用: 如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收

垃圾回收器

串行收集器

新生代串行收集器

复制算法

单线程, 独占式, 进行回收的时候所有线程要停止工作 +XX:+UseSerialGC

老年代串行收集器:

标记压缩算法

较大应用程序会停顿很长时间

-XX:+UseSerialGC 新, 老年代都用串行收集器

-XX:+UseParNewGC 新生代用并行回收器, 老年代用串行

-XX:+UseParallelGC 新生代用ParaParallelGC, 老年代用串行

并行收集器

新生代ParNew回收器

复制算法

简单地用多线程代替单线程, 程序会停顿

-XX:+UseParNewGC 新生代用ParNew,老年代用串行

-XX:+UseConcMarkSweepGC 新生代用ParNew, 老年代用CMS

-XX:+ParallelGCThreads 指定回收线程数,一般和cpu数量相当

新生代ParallelGC回收器

复制算法

重要参数:

-XX:MaxGCPauseMillis: 最大垃圾收集停顿时间,如果设置得太小,会导致jvm新建一个较小的堆,加多垃圾回收频率,所以不是越小越好

-XX:GCTimeRatio: 默认值是19,意思是不超所1%的时间用于垃圾回收

-XX:+UseAdaptiveSizeProxy: 打开自适应GC策略,手工调整比较困难的时候,只要设置最大堆, 目标吞吐量, 停顿时间, 让虚拟机自己完成调优

老年代ParallelOldGC回收器

标记压缩算法

-XX:+UseParUseParallelGC 新生代用ParallelGC回收器,老年代用ParallelOldGC回收器

CMS收集器

主要关注系统停顿时间

使用标记清除算法,多线程垃圾回收器,非独占式

初始标记(独占), 并发标记, 预清理, 重新标记(独占), 并发清除, 并发重置

5f1c7527054a8c1582c43b05072bab61.png

5d46af67b929a067bc458193ec20ea4f.png

启用CMS垃圾回收器 -XX:+UseConcMarkSweepGC

-XX:CMSSInitiatingOccupancyFraction 指定回收阈值,默认是68,当老年代空间使用率达到68会执行一次回收,如果内存增长快,在CMS过程中已经出现了内存不足情况,这个时候CMS会失败,虚拟机自动启动老年代的串行收集器,让程序停顿,直到垃圾回收完成

当执行标记清除算法后,会存在不完整的内存碎片,需要用-XX:+UseCMSCompactAtFullCollection设置当进行多少次CMS回收后,进行一次内存压缩

G1收集器

5ab79989c240228522b54a3e4961b100.png

新生代GC, 并发标记周期(初始标记, 根区域扫描, 并发标记, 重新标记, 独占清理, 并发清理阶段), 混合回收(), 需要则进行FullGC

G1会优先回收垃圾比例较高的区域

-XX:+UseG1GC 打开G1收集器开关

-XX:MaxGCPauseMillis 指定目标最大停顿时间

-XX:ParallelGCThreads 设置并行回收时,GC工作线程数量

大对象当Eden空间不够时,会直接进入老年代,但是体积不是太大的对象有可能优先在TLAB中分配

087fb6c58de80feba10c60411a1872fc.png

不推荐使用Finalize()原因

66ca2fc762afce84da320e356413fc6d.png

性能监控工具

系统性能监控:top, vmstat 监控内存和cpu, iostat 监控IO

jvm性能监控工具

jstat -gc 20212 查看各个空间的情况

jstat -gccause 20212 查看最近GC的原因

jinfo -flag MaxTenuringThreshold 20212 查看某个参数的设置值,还可以动态开关参数jinfo -flag +PrintGCDetails 20212**

jmap -histo 20212 > D:\aaa.txt 获取对象统计信息

jmap -dump:format=b,file=D:\aa.hprof 20212 生成堆快照,然后用jdk自带工具jvisualvm打开hprof文件可以看到哪个对象很大,帮助定位问题

jmap -finalizerinfo 20212 查看对象有没有堆积在finalizer队列中

jstack -l 16016 > D:\d.txt 查看死锁原因

分配的堆空间太小

锁与并发

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值