为什么要故意消耗Cpu和内存?在项目交付时有时会申请一定的资源进行项目程序代码的部署,一般会预留一些Cpu和内存,以便后续扩展项目时能有足够的资源,但有时往往要求很严格,会时不时的检查你的服务器的cpu及内存有没有达到一定的使用率要求,如要求cpu使用率在60%以上,内存在70%以上,如果发现没有达到,为了节省资源,则可能会将配置回收,比如减掉你的cpu及内存数量,基于此,使用Java程序来空跑业务,来消耗Cpu及内存。
1.直接上代码
就一个Java类,如下:
importjava.util.Vector;/***Cpu部分代码参考https://blog.csdn.net/java2000_net/article/details/3136124*@authorjxlhl**/publicclassResouceManageService{//是否跑消耗内存代码的标记,默认否,即跑消耗Cpu的代码privatestaticbooleanmemConsume=false;publicstaticvoidmain(String[]args)throwsException{finalResouceManageServiceservice=newResouceManageService();intnum=1;for(inti=0;i<args.length;i++){//指定-m表明跑消耗内存,指定-c或不指定为消耗Cpu,if("-c".equals(args[i])){}elseif("-m".equals(args[i])){memConsume=true;num=Integer.parseInt(args[i+1]);i++;}}if(memConsume){service.memConsume(num);}else{service.cpuConsume();}}//只内存消耗调用这个方法@SuppressWarnings("unchecked")publicvoidmemConsume(intnum){//执行一个for循环进行新生代内存的申请,共消耗num数量GBfor(inti=0;i<num*10;i++){@SuppressWarnings("rawtypes")Vectorv=newVector();byteb1[]=newbyte[104857600];//100Mv.add(b1);/*System.out.println(v);Runtimert=Runtime.getRuntime();System.out.println("freememory"+rt.freeMemory());*/}//内存消耗申请完后,执行死循环休眠,让JVM一直占用申请到的内存,达到一直占用num数量GB的效果while(true){try{Thread.sleep(3600000l);}catch(InterruptedExceptione){e.printStackTrace();}}}//cpu消耗方法publicvoidcpuConsume(){//角度的分割finaldoubleSPLIT=0.01;////2PI分割的次数,也就是2/0.01个,正好是一周finalintCOUNT=(int)(2/SPLIT);finaldoublePI=Math.PI;//时间间隔finalintINTERVAL=200;long[]busySpan=newlong[COUNT];long[]idleSpan=newlong[COUNT];inthalf=INTERVAL/2;doubleradian=0.0;for(inti=0;i<COUNT;i++){busySpan[i]=(long)(half+(Math.sin(PI*radian)*half));idleSpan[i]=INTERVAL-busySpan[i];radian+=SPLIT;}longstartTime=0;intj=0;while(true){j=j%COUNT;startTime=System.currentTimeMillis();while(System.currentTimeMillis()-startTime<busySpan[j]);try{//这里的if控制可以注解掉,让Thread.sleep(idleSpan[j])一直执行。//我这里加了if控制是因为希望Cpu一直保存在70%以上工作的效果(小于70不sleep),If注解掉将以正弦曲线的趋势使用Cpuif(idleSpan[j]<70){Thread.sleep(idleSpan[j]);}}catch(InterruptedExceptione){e.printStackTrace();}j++;}}}
2.消耗Cpu命令
因为是消耗Cpu,因此在配置Jvm时使用了最少的64M进行启动,如下:
java-XX:InitialHeapSize=64m-XX:MaxHeapSize=64m-XX:NewSize=32m-XX:MaxNewSize=32m-XX:+UseParNewGC-XX:+UseConcMarkSweepGC-XX:PretenureSizeThreshold=10m-cp"."ResouceManageService&
3.消耗内存命令
java-XX:InitialHeapSize=4096m-XX:MaxHeapSize=4096m-XX:NewSize=3072m-XX:MaxNewSize=3072m-XX:+UseParNewGC-XX:+UseConcMarkSweepGC-XX:PretenureSizeThreshold=500m-cp"."ResouceManageService-m1&
参数说明:
-m 表示消耗内存,无此参数表示消耗Cpu, -m后面的数字1表明消耗1G内存
原理: 启动命令时申请最大堆内存4096Mb,新生代3072M,程序在启动时将产生 -m后面数字的内存的数据放在list中,然后申请完后,就一直休眠。这样来达到消耗内存不释放的目的。
因此-m后面的数据不能超过新生代配置的内存的最大值,如果需要超过,就把最大内存和新生代的内存配置增加后再启动,如需要一次性消号6Gb内存,可用如下示例配置:
java -XX:InitialHeapSize=8192m -XX:MaxHeapSize=8192m -XX:NewSize=7168m -XX:MaxNewSize=7168m -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:PretenureSizeThreshold=500m -cp "." ResouceManageService -m 1 &
XX:PretenureSizeThreshold设置成了500MB,是因为我的代码的这一句,byte b1[] = new byte[104857600]; //100M,里面一次申请内存就100M,为避免申请的对象进入老年代,将XX:PretenureSizeThreshold设置调大了
以上命令,可考虑放在shell中保存,以方便执行,如:####vistart-cpu.sh#!/bin/shjava-XX:InitialHeapSize=64m-XX:MaxHeapSize=64m-XX:NewSize=32m-XX:MaxNewSize=32m-XX:+UseParNewGC-XX:+UseConcMarkSweepGC-XX:PretenureSizeThreshold=10m-cp"."ResouceManageService&####vistart-mem.sh#!/bin/shjava-XX:InitialHeapSize=4096m-XX:MaxHeapSize=4096m-XX:NewSize=3072m-XX:MaxNewSize=3072m-XX:+UseParNewGC-XX:+UseConcMarkSweepGC-XX:PretenureSizeThreshold=500m-cp"."ResouceManageService-m1&