JVM(六):性能调优分析


prtyaa
prtyaa 2023-12-28 16:29:43 64346
分类专栏: 资讯

-Xms 是指堆的最小内存:意思是回收到最小内存的时候,就不再回收了,假如-Xms是2G,那么当程序启动的时候,会向OS申请堆内存,一点点申请,不够了再申请,直到申请到堆的最大内存,如果还需要内存的话,那么就内存溢出,如果产生垃圾进行回收的话,回收到堆的最小内存的时候,就不再继续回收了。也不是不回收了,只是回收到堆得最小内存的时候,回收的那些内存会返回给OS,如果还在继续往小于堆最小内存的方向回收的话,回收的内存就不会返回给OS了。

 

如果程序刚开始需要大量内存,不希望一点点去申请,那么可以设置-XX:AlwaysPreTouch参数

 

向开始说的那样,不停的申请内存会出现什么情况呢?

public class FullGCDemo {
    // -Xmx512m -server -verbose:gc -XX:+PrintGCDetails
    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 1000; i++) {
            byte[] tem = new byte[1024 * 1024 * 256];
            System.out.println("running......");
            Thread.sleep(2000L);
        }
    }
}

这个程序时间有点长了,这个程序之所以没有OOM的原因是:创建256M的byte类型的数组,虽然对象在堆里,但是引用是在栈里,出了for循环引用就清空了。

然后再第二次循环的时候,继续创建256M的数组,这属于大对象,大对象是直接进入到老年代的,这时候因为老年代只有341M内存,再申请256M的内存用来存数组的话,老年代存不下了,那么就产生Full GC(虽然老年代有341内存,但是实际上可能不到整的341M.)

发生了Full GC后,之前申请的那个256M的数组就被回收了。所以不会发生OOM

当创建的容量超过老年代的内存的时候,就会发生OOM,设置的堆内存是512M,那么默认新生代老年代比例是 :1比2,老年代就占用341M。

当创建340M的数组的时候,不会OOM,而是Full GC。
创建341M的数组的时候就是OOM

 

但是:当执行Full GC后空间仍然不足的时候,也会抛出OOM

还有一种情况会造成Full gc:手动调用System.gc()或者使用一些工具的api的时候api里自带的会有System.gc(),会产生Full gc。例如jxl工具类里。

使用Btrace可以跟踪Full GC的具体位置。


当引用还在的时候,会造成oom,list在for循环里不停的add,但是list是在for循环外定义的。作用域要理解

public class FullGCDemo {
    // -Xmx512m -server -verbose:gc -XX:+PrintGCDetails
    public static void main(String[] args) throws InterruptedException {
        ArrayList<Object> list = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            list.add(new byte[1024*1024*64]);
            System.out.println("添加成功");
            Thread.sleep(1000L);  //先执行Full GC 随后OOM
        }
    }
}

//控制台
E:\Java\jdk1.8.0_131\bin\java.exe -Xmx512m -server -verbose:gc -XX:+PrintGCDetails "-javaagent:F:\JetBrains\IntelliJ IDEA 2019.2.4\lib\idea_rt.jar=63154:F:\JetBrains\IntelliJ IDEA 2019.2.4\bin" -Dfile.encoding=UTF-8 -classpath E:\Java\jdk1.8.0_131\jre\lib\charsets.jar;E:\Java\jdk1.8.0_131\jre\lib\deploy.jar;E:\Java\jdk1.8.0_131\jre\lib\ext\access-bridge-64.jar;E:\Java\jdk1.8.0_131\jre\lib\ext\cldrdata.jar;E:\Java\jdk1.8.0_131\jre\lib\ext\dnsns.jar;E:\Java\jdk1.8.0_131\jre\lib\ext\jaccess.jar;E:\Java\jdk1.8.0_131\jre\lib\ext\jfxrt.jar;E:\Java\jdk1.8.0_131\jre\lib\ext\localedata.jar;E:\Java\jdk1.8.0_131\jre\lib\ext\nashorn.jar;E:\Java\jdk1.8.0_131\jre\lib\ext\sunec.jar;E:\Java\jdk1.8.0_131\jre\lib\ext\sunjce_provider.jar;E:\Java\jdk1.8.0_131\jre\lib\ext\sunmscapi.jar;E:\Java\jdk1.8.0_131\jre\lib\ext\sunpkcs11.jar;E:\Java\jdk1.8.0_131\jre\lib\ext\zipfs.jar;E:\Java\jdk1.8.0_131\jre\lib\javaws.jar;E:\Java\jdk1.8.0_131\jre\lib\jce.jar;E:\Java\jdk1.8.0_131\jre\lib\jfr.jar;E:\Java\jdk1.8.0_131\jre\lib\jfxswt.jar;E:\Java\jdk1.8.0_131\jre\lib\jsse.jar;E:\Java\jdk1.8.0_131\jre\lib\management-agent.jar;E:\Java\jdk1.8.0_131\jre\lib\plugin.jar;E:\Java\jdk1.8.0_131\jre\lib\resources.jar;E:\Java\jdk1.8.0_131\jre\lib\rt.jar;F:\workspace_idea\untitled_tiaoyou\out\production\untitled_tiaoyou FullGCDemo
添加成功
添加成功
添加成功
添加成功
添加成功
[GC (Allocation Failure) [PSYoungGen: 6510K->1208K(75776K)] 334190K->328896K(425472K), 0.0023030 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 1208K->1144K(75776K)] 328896K->328832K(425472K), 0.0022520 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Allocation Failure) [PSYoungGen: 1144K->0K(75776K)] [ParOldGen: 327688K->328668K(349696K)] 328832K->328668K(425472K), [Metaspace: 3993K->3993K(1056768K)], 0.0112951 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
[GC (Allocation Failure) [PSYoungGen: 0K->0K(75776K)] 328668K->328668K(425472K), 0.0009928 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Allocation Failure) [PSYoungGen: 0K->0K(75776K)] [ParOldGen: 328668K->328615K(349696K)] 328668K->328615K(425472K), [Metaspace: 3993K->3993K(1056768K)], 0.0077370 secs] [Times: user=0.14 sys=0.02, real=0.01 secs] 
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at FullGCDemo.main(FullGCDemo.java:9)
Heap
 PSYoungGen      total 75776K, used 1734K [0x00000000f5580000, 0x00000000fe980000, 0x0000000100000000)
  eden space 65024K, 2% used [0x00000000f5580000,0x00000000f5731970,0x00000000f9500000)
  from space 10752K, 0% used [0x00000000f9500000,0x00000000f9500000,0x00000000f9f80000)
  to   space 10752K, 0% used [0x00000000fdf00000,0x00000000fdf00000,0x00000000fe980000)
 ParOldGen       total 349696K, used 328615K [0x00000000e0000000, 0x00000000f5580000, 0x00000000f5580000)
  object space 349696K, 93% used [0x00000000e0000000,0x00000000f40e9e68,0x00000000f5580000)
 Metaspace       used 4024K, capacity 4568K, committed 4864K, reserved 1056768K
  class space    used 450K, capacity 460K, committed 512K, reserved 1048576K

Process finished with exit code 1

如果在这个for循环里调用system.gc也是回收不了内存的,要想gc,也得达到gc的条件吧,可达性分析了解一下。这个list是可达的,还是持有引用的。


那项目中OOM了可以dump到磁盘上,然后用eclipse Memory Analyzer或者用

来分析。

网站声明:如果转载,请联系本站管理员。否则一切后果自行承担。

本文链接:https://www.xckfsq.com/news/show.html?id=31821
赞同 0
评论 0 条
prtyaaL0
粉丝 1 发表 2554 + 关注 私信
上周热门
银河麒麟添加网络打印机时,出现“client-error-not-possible”错误提示  1448
银河麒麟打印带有图像的文档时出错  1365
银河麒麟添加打印机时,出现“server-error-internal-error”  1151
统信桌面专业版【如何查询系统安装时间】  1073
统信操作系统各版本介绍  1070
统信桌面专业版【全盘安装UOS系统】介绍  1028
麒麟系统也能完整体验微信啦!  984
统信【启动盘制作工具】使用介绍  627
统信桌面专业版【一个U盘做多个系统启动盘】的方法  575
信刻全自动档案蓝光光盘检测一体机  484
本周热议
我的信创开放社区兼职赚钱历程 40
今天你签到了吗? 27
信创开放社区邀请他人注册的具体步骤如下 15
如何玩转信创开放社区—从小白进阶到专家 15
方德桌面操作系统 14
我有15积分有什么用? 13
用抖音玩法闯信创开放社区——用平台宣传企业产品服务 13
如何让你先人一步获得悬赏问题信息?(创作者必看) 12
2024中国信创产业发展大会暨中国信息科技创新与应用博览会 9
中央国家机关政府采购中心:应当将CPU、操作系统符合安全可靠测评要求纳入采购需求 8

添加我为好友,拉您入交流群!

请使用微信扫一扫!