JVM
JVM从入门到放弃
绅士jiejie
理想的生活,就是生活的理想!
展开
-
代码生成CompressedClassSpace的OOM错误
代码生成CompressedClassSpace的OOM错误原创 2024-03-17 10:46:06 · 464 阅读 · 0 评论 -
The Java thread stack size specified is too small. Specify at least 208k
The Java thread stack size specified is too small. Specify at least 208k原创 2024-02-03 17:05:41 · 459 阅读 · 0 评论 -
准备阶段-各类型变量默认初始值
准备阶段-各类型变量默认初始值原创 2023-07-16 10:08:44 · 144 阅读 · 0 评论 -
JVM字节码指令集分类
JVM字节码指令集分类原创 2023-07-15 21:58:46 · 65 阅读 · 0 评论 -
从字节码的角度理解,为什么静态方法不能被重写
从字节码的角度理解,为什么静态方法不能被重写原创 2023-07-15 21:58:14 · 117 阅读 · 0 评论 -
为什么不把基本类型放堆中?
为什么不把基本类型放堆中?原创 2023-07-15 21:57:37 · 91 阅读 · 0 评论 -
简单了解下字面量与符号引用
简单了解下字面量与符号引用原创 2023-07-15 21:57:03 · 50 阅读 · 0 评论 -
GC时候会回收线程?
GC时候会回收线程?原创 2022-05-05 22:04:49 · 960 阅读 · 0 评论 -
面试题:有没有jvm调优经验?调优⽅方案有哪些?
一.何时需要调优堆中老年代内存持续上涨,达到设置的最大内存上限Full GC次数频繁,导致STW次数过多,影响系统性能GC停顿时间过长,超过1秒就得注意了应用直接报出OutOfMemory 等内存异常提示应⽤中有使⽤本地缓存且该缓存占⽤了大量的内存空间参考监控数据,发现系统吞吐量与响应性能不高甚至出现下降情况二.调优原则大多数的java应用不需要在服务器上进行jvm优化要深知多数出现GC问题的java应用,可能不是因为我们jvm参数设置错误,反而可能是代码问题引起的尽量减少创建的对原创 2021-11-04 17:41:21 · 345 阅读 · 0 评论 -
从内存的角度怎么估测可以创建的最大线程数?
(操作系统最大可用内存 - JVM内存 - 操作系统预留内存)/线程栈大小=最大线程数原创 2020-10-28 21:01:58 · 246 阅读 · 0 评论 -
符号引用和直接引用有什么区别
符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能够无歧义的定位到目标即可,使用符号引用时,被引用的目标不一定已经加载到内存中。直接引用可以是直接指向目标的指针,相对偏移量,一个能间接定位到目标的句柄,使用直接引用时,引用的目标必定已经存在于虚拟机的内存中了。为什么在解析阶段要符号引用转直接引用?个人理解,如果使用符号引用,虚拟机其实也不知道具体引用的类的内存地址,那么也就无法真正的调用到该类,所以要把符号引用转为直接引用,这样就能够真正定位到类在内存中的地址,如果符号原创 2020-10-23 12:08:12 · 5074 阅读 · 4 评论 -
标记-整理算法是先清除后整理?
标记-整理算法是先标记出存活对象,接着把所有的存活对象移动到内存的一端,然后把另一端的所有垃圾对象全部清除。因此标记-整理算法是先整理内存空间再清除垃圾对象的,而不是先清除再整理。...原创 2020-10-23 12:07:30 · 499 阅读 · 0 评论 -
调大Eden区会增加Minor GC的时间?
首先反驳一下调大Eden区会增加Minor GC的说法,这里我们可以简单的把Minor GC分为两步骤,一是扫描新生代(T1),二是复制存活对象(T2),所以整个Minor GC的时间就是T1+T2。而增大Eden区,Eden区中能够容纳的存活对象可能会更多,自然也就推迟了Minor GC被触发的时间,毕竟只有Eden区满了才会触发Minor GC。假设有一个对象,能够存活500ms的时间,而Minor GC的间隔是300ms,那么此时该对象的Minor GC的时间T1+T2,然后增加Eden区内存原创 2020-10-21 12:07:40 · 742 阅读 · 0 评论 -
GC的打印基于日期的时间戳
在JVM参数中加上-XX:+PrintGCDateStamps参数。GC信息效果如下:原创 2020-10-21 12:05:43 · 2018 阅读 · 0 评论 -
垃圾收集时,是先获得有效对象还是垃圾对象?
以下是个人对于这个问题的见解。判断对象是否是有效对象,采用的是GC Root的方式,如果对象和GC Root能够有相应的GC Root链相连,说明对象是有效的,否则对象是无效的。所以每次判断都应该是先从GC Root出发,标记出引用的对象,然后剩下的没被标记的对象就是垃圾对象了,所以垃圾收集时是先获取有效对象,而不能直接获取垃圾对象。接下来可以简单了解下3种算法的回收垃圾的思路:复制算法:标记出存活对象,把他们移动到另一个空白的内存,然后清空原来空间,因为剩下的对象都是垃圾对象了。标记-清除.原创 2020-10-20 20:57:20 · 188 阅读 · 0 评论 -
分享一下JVM参数模版
首先需要自己根据机器的配置设置JVM中各区域的初步大小,如下:-Xms4096M-Xmx4096M-Xmn3072M-Xss1M-XX:MetaspaceSize=256M-XX:MaxMetaspaceSize=256M接着需要指定垃圾回收器,G1的话,其实可调优不多,一般使用停顿时间参数就好,所以这里使用ParNew+CMS,参数如下:-XX:+UseParNewGC-XX:+UseConcMarkSweepGC-XX:CMSInitiatingOccupancyFraction=原创 2020-10-20 12:07:01 · 299 阅读 · 0 评论 -
-XX:CMSInitiatingOccupancyFraction和-XX:+UseCMSInitiatingOccupancyOnly参数
-XX:CMSInitiatingOccupancyFraction:在使用CMS收集器的情况下,指定老年代被使用的内存空间的阈值,达到该阈值则触发Full GC。-XX:+UseCMSInitiatingOccupancyOnly:指定用设定的回收阈值(-XX:CMSInitiatingOccupancyFraction参数的值),如果不指定,JVM仅在第一次使用设定值,后续则会根据运行时采集的数据做自动调整,如果指定了该参数,那么每次JVM都会在到达规定设定值时才进行GC。不过大多数情况下,JVM都能原创 2020-10-19 18:52:21 · 5139 阅读 · 0 评论 -
-XX:+PrintHeapAtGC参数使用了解
一般来说,JVM在运行中,是没法直接了解到堆的概况的,只有程序结束后,才会在最后输出堆的概况,参考如下:可以发现,停止了程序后,才输出了堆的概况。而如果想要知道每次GC前后,GC堆的概况,就可以加上【-XX:+PrintHeapAtGC】参数,然后输出结果参考如下:截图中很直观地输出了GC前后堆的概况。...原创 2020-10-19 18:49:53 · 3709 阅读 · 0 评论 -
使用MAT分析简单分析内存快照文件
首先打开MAT软件,如下:选择打开一个Dump快照文件,如下:勾选上图红框部分,表示要进行内存泄漏的分析。出现饼状图,如下所示:接着MAT还会列出几个可能存在内存泄漏的问题,拿第一个问题来分析,如下:这个问题已经表示的很清晰了,main线程通过局部变量引用的对象占用了32.04%左右的内存空间,然后这些对象是一个java.lang.Object[]数组。先点击Details看下详细信息,如下:以从上到下的顺序看下来,可以发现是main线程中引用了一个ArrayList对象,ArrayList对原创 2020-10-19 18:48:38 · 777 阅读 · 0 评论 -
使用Jmap命令导出内存快照
先用jps命令找到进程号,然后参照示例:jmap -dump:live,format=b,file=heap.bin <pid>其实如果jmap命令写错了,就会给出以上的例子作为提示。具体实现:jmap -dump:live,format=b,file=heap.bin 3674导出后再通过jhat或者MAT工具来分析内存。...原创 2020-10-19 18:42:50 · 2495 阅读 · 0 评论 -
-XX:+TraceClassLoading和-XX:+TraceClassUnloading
顾名思义,-XX:+TraceClassLoading和-XX:+TraceClassUnloading这两个参数可以跟踪类加载和卸载的情况。这两个参数有什么使用思路?如果碰到经常Full GC的情况,但是老年代空间使用的却不多,年轻代GC后的情况也很正常,同时也不存在突然大对象的情况,但是元空间却一直递增,那么可以考虑下是不是使用了反射等手段导致元空间加载的类太多了,导致元空间爆满触发Full GC,那么此时就可以加上-XX:+TraceClassLoading和-XX:+TraceClassUn原创 2020-10-19 18:41:46 · 3700 阅读 · 0 评论 -
-XX:SoftRefLRUPolicyMSPerMB参数了解
以上参数会影响软引用对象被回收的情况。对于软引用对象,只要堆内存不够了,该对象就会被回收来释放空间。不过这只是理论,软引用对象能够被回收需要满足一定的逻辑判断,判断公式如下:clock - timestamp <= freespace * SoftRefLRUPolicyMSPerMBclock表示上次GC的时间戳,timestamp表示最近一次读取软引用对象的时间戳,这两者的差值表示该软引用对象多久没被使用了,差值越大,软引用对象价值越低,负数则表示软引用对象刚刚被使用。freespace是原创 2020-10-19 18:41:16 · 7099 阅读 · 2 评论 -
如果发生oldGC,即使survivor区放的下部分存活对象,对象也会全部进入老年代
调整虚拟机参数如下:-XX:NewSize=104857600—新生代大小为100m-XX:MaxNewSize=104857600—新生代最大大小为100m-Xms200M—初始堆大小为200m-Xmx200M—最大堆大小为200m-XX:+UseParNewGC:新生代使用ParNewGC垃圾回收器-XX:+UseConcMarkSweepGC---老年代使用CMS-XX:+PrintGCDetails---打印GC详细日志-XX:+PrintGCTimeStamps—打印GC时间.原创 2020-10-18 17:09:43 · 715 阅读 · 0 评论 -
年轻代gc耗时真的比老年代短?
调整JVM参数如下:-XX:NewSize=104857600—新生代大小为100m-XX:MaxNewSize=104857600—新生代最大大小为100m-Xms200M—初始堆大小为200m-Xmx200M—最大堆大小为200m-XX:+UseParNewGC:新生代使用ParNewGC垃圾回收器-XX:+UseConcMarkSweepGC---老年代使用CMS-XX:+PrintGCDetails---打印GC详细日志-XX:+PrintGCTimeStamps—打印GC时间.原创 2020-10-18 14:29:16 · 950 阅读 · 1 评论 -
了解下jstat命令的使用
调整JVM参数如下:-XX:NewSize=104857600—新生代大小为100m-XX:MaxNewSize=104857600—新生代最大大小为100m-Xms20M—初始堆大小为200m-Xmx20M—最大堆大小为200m-XX:+UseParNewGC:新生代使用ParNewGC垃圾回收器-XX:+UseConcMarkSweepGC---老年代使用CMS-XX:+PrintGCDetails---打印GC详细日志-XX:+PrintGCTimeStamps—打印GC时间-X.原创 2020-10-17 13:40:23 · 658 阅读 · 1 评论 -
对象自然进入老年代
调整JVM参数如下:-XX:NewSize=10485760—新生代大小为10m-XX:MaxNewSize=10485760—新生代最大大小为10m-Xms20M—初始堆大小为20m-Xmx20M—最大堆大小为20m-XX:+UseParNewGC:新生代使用ParNewGC垃圾回收器-XX:+UseConcMarkSweepGC---老年代使用CMS-XX:+PrintGCDetails---打印GC详细日志-XX:+PrintGCTimeStamps—打印GC时间-XX:Surviv原创 2020-10-16 22:52:59 · 160 阅读 · 0 评论 -
-XX:SurvivorRatio参数作用
该参数作用:Eden区与每一个Survivor区的比值举例:-XX:SurvivorRatio=8,这是该参数的默认值,所以Eden:S0:S1=8:1:1-XX:SurvivorRatio=4,Eden:S0:S1=4:1:1,千万不要以为新生代是被分成10份,Eden:S0:S1会是4:3:3,这是错误的。-XX:SurvivorRatio=5,Eden:S0:S1=5:1:1...原创 2020-10-16 22:19:17 · 1554 阅读 · 0 评论 -
GC前后,变量指向的对象不同,前一个对象会被回收么?
调整JVM参数如下:-XX:NewSize=10485760—新生代大小为10m-XX:MaxNewSize=10485760—新生代最大大小为10m-Xms20M—初始堆大小为20m-Xmx20M—最大堆大小为20m-XX:+UseParNewGC:新生代使用ParNewGC垃圾回收器-XX:+UseConcMarkSweepGC---老年代使用CMS-XX:+PrintGCDetails---打印GC详细日志-XX:+PrintGCTimeStamps—打印GC时间-XX:Surviv原创 2020-10-16 19:21:35 · 247 阅读 · 1 评论 -
模拟大对象直接进入老年代场景
调整JVM参数如下:-XX:NewSize=10485760—新生代大小为10m-XX:MaxNewSize=10485760—新生代最大大小为10m-Xms20M—初始堆大小为20m-Xmx20M—最大堆大小为20m-XX:+UseParNewGC:新生代使用ParNewGC垃圾回收器-XX:+UseConcMarkSweepGC---老年代使用CMS-XX:+PrintGCDetails---打印GC详细日志-XX:+PrintGCTimeStamps—打印GC时间-XX:Surviv原创 2020-10-16 19:20:24 · 349 阅读 · 0 评论 -
Survivor区放不下存活对象,那么存活对象直接就分配到老年代?
调整JVM参数如下:-XX:NewSize=10485760—新生代大小为10m-XX:MaxNewSize=10485760—新生代最大大小为10m-Xms20M—初始堆大小为20m-Xmx20M—最大堆大小为20m-XX:+UseParNewGC:新生代使用ParNewGC垃圾回收器-XX:+UseConcMarkSweepGC---老年代使用CMS-XX:+PrintGCDetails---打印GC详细日志-XX:+PrintGCTimeStamps—打印GC时间-XX:Surviv原创 2020-10-16 19:18:49 · 1978 阅读 · 2 评论 -
动态年龄判断是下一次年轻代GC后才会判断的事
调整JVM参数如下:-XX:NewSize=10485760—新生代大小为10m-XX:MaxNewSize=10485760—新生代最大大小为10m-Xms20M—初始堆大小为20m-Xmx20M—最大堆大小为20m-XX:+UseParNewGC:新生代使用ParNewGC垃圾回收器-XX:+UseConcMarkSweepGC---老年代使用CMS-XX:+PrintGCDetails---打印GC详细日志-XX:+PrintGCTimeStamps—打印GC时间-XX:Surviv原创 2020-10-16 19:17:02 · 611 阅读 · 1 评论 -
怎么去预估上线系统的JVM参数?
分析系统的背景和核心业务是什么举例:比如系统是教育erp报班系统,那么核心业务就是买课业务。预估高峰时长以及当时的活跃用户量,系统上线前如果没有具体数据可以参考,可以先和产品大致了解下用户情况,然后根据情况提高几倍量级来预估举例:比如买课报班就维持一个小时,一般是在早上9:00~10:00,当时的活跃用户量大致有一万,保险起见,提高3倍,大概三万用户。预估这段时间会产生多少请求举例:买课报班操作一般不会太频繁,假设一个用户只报一门课,大致一小时是3万个请求,保险起见,在这个基础上再增加.原创 2020-10-16 19:14:30 · 311 阅读 · 0 评论 -
了解下-XX:G1MixedGCLiveThresholdPercent参数
该参数的默认值是85%。规定只有存活对象低于85%的Region才可以被回收。为什么要有这个规定?因为G1是基于复制算法来处理垃圾对象的,把存活对象复制到另一个空闲的Region,剩下的就是垃圾对象了,然后就可以直接回收整个Region。试想下,如果一个Region中的存活对象大于85%,把这85%对象都复制到另一个空闲的Region,成本还是很高的,而且Region改变也不大,所以回收价值不高,因此可以让G1把有限的时间拿去回收那些回收价值更大的Region,以此把GC停顿时间控制在范围内。调原创 2020-10-16 19:12:43 · 3155 阅读 · 1 评论 -
加载的类真的能够被卸载?
按逻辑来说,一旦类使用完,没有相关引用,就可以被卸载了,不过类可以被卸载的条件之一是加载该类的类加载器ClassLoader已经被回收了,而JVM虚拟机自带的3种类加载器是不会被卸载的,所以可以得出只要是JVM虚拟机自带的3种类加载器加载的类,加载后就不会再被卸载,那什么类可以被卸载?就只有自定义的类加载器加载的类了。...原创 2020-10-16 19:09:50 · 418 阅读 · 0 评论 -
JVM参数选项规则了解
java -version:标准选项,任何版本JVM/任何平台都可以使用java -Xms6m:非标准选项,部分版本识别java -XX:PrintGCDetails:不稳定参数,JVM不同也会有差异,该参数随时可能被移除PS:+代表开启/-代表关闭...原创 2020-10-15 19:41:46 · 157 阅读 · 0 评论 -
G1还有新生代和老年代么?
G1依旧存在着老年代和新生代,只不过相比起CMS等垃圾回收器将新生代和老年代区域划分的那么明显, 在G1中,老年代和新生代逐渐变成逻辑上的概念了。首先G1将整个堆内存划分成一个个Region,可以先将这个Region想像成是个完全中立的内存空间,它没有任何归属。随着程序的运行,对象会不断被新建,这些对象首先会进入年轻代,但是此时G1只有Region的概念,那么这些被分配到新对象的Region就是属于年轻代,慢慢的,随着对象的增多,就触发了GC,存活的对象就会被分配到其他空闲的Region,此时这些Regio原创 2020-10-15 19:40:56 · 3473 阅读 · 1 评论 -
简单的了解下G1是怎么做到控制垃圾回收停顿时间的?
G1可以设置一个垃圾回收的预期停顿时间,制定一个目标,规定在一个时间内,垃圾回收引起的停顿时间不能超过多久,之后就由G1来全权负责,保证达到该目标。想想之前的几款垃圾回收器,费尽心思的优化参数,最终其实还是为了减少STW的时间,提高吞吐量,而G1直接就做到由开发者来指定STW时间,相比起其他垃圾回收器,无疑显得更智能和友好。而G1能够做到控制垃圾回收停顿时间的关键在于,它要追踪每个Region的回收价值,它要清楚每个Region里有多少对象是垃圾,如果对这个Region做回收,会消耗多少时间,尽量在有限的原创 2020-10-15 19:38:34 · 3251 阅读 · 1 评论 -
大对象在G1中会直接被分配到老年代么?
什么才算是大对象?在G1中,一个对象的大小超过了一个Region大小的50%,就是大对象。大对象怎么分配?大对象在G1中不会直接被分配到老年代,或者说大对象就根本不会进入老年代。G1是将堆内存分为一块块的Region,这些Region有时属于老年代有时属于年轻代,具体看G1怎么分配。同样的如果有大对象需要分配,也是分配到那些尚未被占据的Region,这些Region可以称为是大对象专门的Region。如果对象太大了,也可以横跨多个Region来存放。大对象怎么回收?在老年代触发混合回收.原创 2020-10-15 19:36:33 · 3185 阅读 · 0 评论 -
G1的混合回收次数默认是8次?
G1的混合回收阶段是可以分多次进行的,但每次都会进入STW状态,次数默认是8次。运行逻辑是先STW,执行一次混合回收回收掉一些Region,接着恢复系统运行,然后再STW,再执行混合回收,如此反复多次直到空闲的Region数量达到堆内存的5%才停止。那么混合回收次数就是8次么?这个只是默认值,可以通过参数【-XX:G1MixedGCCountTarget】来调整,事实上,混合回收阶段具体执行几次回收,看的是空闲的Region数量何时达到堆内存的5%,如果执行3次回收就达到了5%,就不会再继续执行回收原创 2020-10-15 19:34:58 · 587 阅读 · 0 评论 -
使用G1优化大内存机器
普通的4核8G机器算不上什么大内存,假设机器分配给JVM的内存空间是全部内存的2/3左右,新生代大概会被分配1.5G左右的内存,Eden区大致在1G左右,使用ParNew+CMS组合垃圾回收器就好。而一旦升级到16核32G这种大内存机器,分配给堆的内存空间肯定也会水涨船高。这时候想想,升级前可能新生代GC只要关注回收那1G左右的内存空间,而升级后,新生代能够分配到的内存空间大概会有6G左右,Eden区大致在5G左右,相比之下此时新生代GC时要关注回收的内存就大的多了,速度自然也很会减慢,当开发者发现此时的新原创 2020-10-15 19:29:26 · 1308 阅读 · 0 评论