美文网首页
使用Java故意消耗Cpu和内存的代码

使用Java故意消耗Cpu和内存的代码

作者: Yobhel | 来源:发表于2022-08-25 14:56 被阅读0次

【摘要】 为什么要故意消耗Cpu和内存?在项目交付时有时会申请一定的资源进行项目程序代码的部署,一般会预留一些Cpu和内存,以便后续扩展项目时能有足够的资源,但有时往往要求很严格,会时不时的检查你的服务器的cpu及内存有没有达到一定的使用率要求,如要求cpu使用率在60%以上,内存在70%以上,如果发现没有达到,为了节省资源,则可能会将配置回收,比如减掉你的cpu及内存数量,基于此,使用Java程序来...

为什么要故意消耗Cpu和内存?在项目交付时有时会申请一定的资源进行项目程序代码的部署,一般会预留一些Cpu和内存,以便后续扩展项目时能有足够的资源,但有时往往要求很严格,会时不时的检查你的服务器的cpu及内存有没有达到一定的使用率要求,如要求cpu使用率在60%以上,内存在70%以上,如果发现没有达到,为了节省资源,则可能会将配置回收,比如减掉你的cpu及内存数量,基于此,使用Java程序来空跑业务,来消耗Cpu及内存。

1.直接上代码

就一个Java类,如下:

import java.util.Vector;
/**
 * Cpu部分代码参考https://blog.csdn.net/java2000_net/article/details/3136124
 * @author jxlhl
 *
 */
public class ResouceManageService {

    //是否跑消耗内存代码的标记,默认否,即跑消耗Cpu的代码
    private static boolean memConsume = false;

    public static void main(String[] args) throws Exception {
        
        final ResouceManageService service = new ResouceManageService();
        
        int num = 1;
        
        for (int i = 0; i < args.length; i++) {

            //指定-m表明跑消耗内存,指定-c或不指定为消耗Cpu,
            if ("-c".equals(args[i])) {
                
            } else if ("-m".equals(args[i])) {
                memConsume = true;
                num = Integer.parseInt(args[i + 1]);
                i++;
            }
            
        }
        
        if(memConsume){

            service.memConsume(num);

        }else {
            
            service.cpuConsume();
            
        }
        
    }
    
    //只内存消耗调用这个方法
    @SuppressWarnings("unchecked")
    public void memConsume(int num){

        //执行一个for循环进行新生代内存的申请,共消耗num数量GB
        for(int i=0;i<num * 10;i++){

            @SuppressWarnings("rawtypes")
            Vector v = new Vector();
            byte b1[] = new byte[104857600]; //100M
            v.add(b1);
            /*System.out.println(v);
            Runtime rt = Runtime.getRuntime();
            System.out.println("free memory"+ rt.freeMemory() );*/

        }

        //内存消耗申请完后,执行死循环休眠,让JVM一直占用申请到的内存,达到一直占用num数量GB的效果
        while(true){
            try {
                Thread.sleep(3600000l);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
    }
    
    //cpu消耗方法
    public void cpuConsume(){
        // 角度的分割
        final double SPLIT = 0.01;
        //
        // 2PI分割的次数,也就是2/0.01个,正好是一周
        final int COUNT = (int) (2 / SPLIT);
        final double PI = Math.PI;
        // 时间间隔
        final int INTERVAL = 200;
        long[] busySpan = new long[COUNT];
        long[] idleSpan = new long[COUNT];
        int half = INTERVAL / 2;
        double radian = 0.0;
        for (int i = 0; i < COUNT; i++) {
            busySpan[i] = (long) (half + (Math.sin(PI * radian) * half));
            idleSpan[i] = INTERVAL - busySpan[i];
            radian += SPLIT;
        }
        long startTime = 0;
        int j = 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注解掉将以正弦曲线的趋势使用Cpu
                if(idleSpan[j]<70){
                    Thread.sleep(idleSpan[j]);
                }
                
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            j++;
        }
    }

}

2.消耗Cpu命令

因为是消耗Cpu,因此在配置Jvm时使用了最少的64M进行启动,如下

java -XX:InitialHeapSize=64m -XX:MaxHeapSize=64m -XX:NewSize=32m -XX:MaxNewSize=32m -XX:+UseParNewG

3.消耗内存命令

java -XX:InitialHeapSize=4096m -XX:MaxHeapSize=4096m -XX:NewSize=3072m -XX:MaxNewSize=3072m -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:PretenureSizeThreshold=500m -cp "." ResouceManageService -m 1 &

参数说明:
-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中保存,以方便执行,如:
####vi start-cpu.sh
#!/bin/sh
java -XX:InitialHeapSize=64m -XX:MaxHeapSize=64m -XX:NewSize=32m -XX:MaxNewSize=32m -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:PretenureSizeThreshold=10m -cp "." ResouceManageService &

####vi start-mem.sh
#!/bin/sh
java -XX:InitialHeapSize=4096m -XX:MaxHeapSize=4096m -XX:NewSize=3072m -XX:MaxNewSize=3072m -XX:+Use

相关文章

  • 使用Java故意消耗Cpu和内存的代码

    【摘要】 为什么要故意消耗Cpu和内存?在项目交付时有时会申请一定的资源进行项目程序代码的部署,一般会预留一些Cp...

  • Jmeter&Apache&LR.VS.RPT

    在使用Jmeter进行接口的性能测试时,由于Jmeter 是JAVA应用,对于CPU和内存的消耗比较大,所以,当需...

  • Jmeter - 远程连接多台代理机实现分布式测试

    在使用Jmeter进行接口的性能测试时,由于Jmeter 是JAVA应用,对于CPU和内存的消耗比较大,所以,当需...

  • 2019-02-20 JMeter分布式测试

    一:分布式使用场景及原理 使用场景:由于Jmeter是JAVA应用,对于CPU和内存的消耗比较大,所以,当需要模拟...

  • 05 - Jmeter连接多台电脑做压力测试

     在使用Jmeter进行接口的性能测试时, 由于Jmeter是JAVA应用, 对于CPU的内存消耗比较大, 所以,...

  • JMeter(十三)分布式部署

    Jmeter 是java 应用,对于CPU和内存的消耗比较大,因此,当需要模拟数以千计的并发用户时,使用单台机器模...

  • [转载]JMeter 分布式部署

    Jmeter 是java 应用,对于CPU和内存的消耗比较大,使用单台机器模拟以千计的并发用户就有些力不从心,甚至...

  • 深入理解 Java 内存模型

    深入理解 Java 内存模型(一) 从Java代码到CPU指令 最开始,我们编写Java代码,是java文件。 在...

  • JMeter 分布式负载

    JMeter 是一个100%的纯 JAVA 应用,对机器 CPU 和内存的消耗比较大,在用 JMeter 做并发测...

  • 2020-03-11

    1内存不足,2内存泄漏,3锁争用,4线程锁死,5java进程消耗CPU过高等

网友评论

      本文标题:使用Java故意消耗Cpu和内存的代码

      本文链接:https://www.haomeiwen.com/subject/hzwtnrtx.html