java代码,故意消耗服务器Cpu消耗和内存消耗一定比例

云服务器申请下来长期不用避免被回收,通过下面代码可消耗Cpu消耗和内存消耗,让服务器处于一个合理利用的状态,避免闲置回收

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.lang.ref.SoftReference;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;


public class MemConsumeListener implements ServletContextListener {
    /**
     * cpu 阈值 百分比%
     */
    private static final int Cpu_LOAD_puTHRESHOLD = 15;

    /**
     * 内存 阈值 百分比%
     */
    private static final int Mem_LOAD_THRESHOLD = 30;

    private static volatile boolean shouldRun = true;

    private static volatile boolean MenRun = true;

    private static OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean();

    // 设定最大内存阈值为JVM最大内存的一半
    private static final long MAX_MEMORY_THRESHOLD = Runtime.getRuntime().maxMemory() / 2;

    private static final List<SoftReference<byte[]>> memoryPool = new ArrayList<>();

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        // 在这里写入你需要在Tomcat启动时运行的代码
        System.out.println("启动运行CPU、内存消耗程序...");
        System.out.println("当前JVM内存: "+ MAX_MEMORY_THRESHOLD /(1024 * 1024) + " MB;");
        System.out.println("当前内存阈值: "+ Mem_LOAD_THRESHOLD + "%;");
        System.out.println("当前CPU阈值: "+ Cpu_LOAD_puTHRESHOLD + "%;");
        printInfo();
        //消耗cpu
        CPUBurner();
        try {
            // 消耗内存
            MemoryManager();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("停止运行Tomcat...");
        System.out.println("释放内存");
        memoryPool.clear();
        System.gc();
    }


    public static void CPUBurner() {
        // 假设这是检查CPU使用率的函数,这里用模拟的sleep代替
        Thread checkerThread = new Thread(() -> {
            while (true) {
                // 模拟CPU检查,假设检查每2秒执行一次
                try {
                    Thread.sleep(500);
                    if (getCpuUsage() >= Cpu_LOAD_puTHRESHOLD) {
                        shouldRun = false;
                    }
                    else if(!shouldRun){
                        shouldRun = true;
                        expendCpu();
                    }
                    expendCpu();
                } catch (Exception e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        checkerThread.start();
    }

    private static void expendCpu(){
        // 真正的CPU消耗线程
        Thread consumerThread = new Thread(() -> {
            while (shouldRun) { // 注意:这个循环实际上永远不会自然停止
                for (long j = 0; j < 10; j++) {
                    double result = Math.sin(j) * Math.cos(j);
                }
            }
        });
        consumerThread.start();
    }

    /**
     * 获取cpu使用率
     * @return
     * @throws Exception
     */
    private static double getCpuUsage() throws Exception {
        double cpuLoad = 0l;
        if (osBean instanceof com.sun.management.OperatingSystemMXBean) {
            com.sun.management.OperatingSystemMXBean sunOsBean = (com.sun.management.OperatingSystemMXBean) osBean;
            cpuLoad = sunOsBean.getSystemCpuLoad();
            if (cpuLoad == -1.0) {
                throw  new Exception("系统平均负载不可用");
            }
        }else{
            cpuLoad = osBean.getSystemLoadAverage();
            if (cpuLoad == -1.0) {
                throw  new Exception("系统平均负载不可用");
            }
        }
        //System.out.println("系统平均负载:" + cpuLoad *100);
        return cpuLoad * 100;
    }

    public static void MemoryManager() throws InterruptedException {
        Runtime runtime = Runtime.getRuntime();
        while (true) {
            long freeMemory = runtime.freeMemory();
            long totalMemory = runtime.totalMemory();
            long usedMemory = totalMemory - freeMemory;
//            System.out.print("Total Memory: " + totalMemory / (1024 * 1024) + " MB;");
//            System.out.print("Free Memory: " + freeMemory / (1024 * 1024) + " MB;");
//            System.out.println("Used Memory: " + usedMemory / (1024 * 1024) + " MB;");
            //这边的限制是避免当前运行程序嘎掉
            if (usedMemory < MAX_MEMORY_THRESHOLD && MenRun) {
                // 消耗内存
                consumeMemory();
            }
//            else {
//                // 尝试“释放”内存(通过减少引用)
//                releaseMemory();
//                // 注意:这里并没有直接释放内存,只是减少了对象引用,让JVM有机会回收这些对象
//                // 调用System.gc()请求JVM进行垃圾回收,但JVM可以忽略这个请求
//                System.gc();
//            }

            // 暂停一段时间以便观察效果
            Thread.sleep(1000);
        }
    }

    private static void consumeMemory() {
        byte[] data = new byte[1024 * 1024 * 10]; // 100MB数据 104857600
        memoryPool.add(new SoftReference<>(data)); // 使用软引用,以便在内存紧张时可以被回收
    }

    private static void releaseMemory() {
        if(memoryPool.size() > 0){
            //依次移除memoryPool中的每个对象
            memoryPool.remove(0).clear();
        }
        // 移除引用,让JVM有机会回收这些对象
       //    memoryPool.clear();
    }

    private static void printInfo(){
        Thread consumerThread = new Thread(() -> {
            testSystemUsage();
        });
        consumerThread.start();
    }
    public static void testSystemUsage() {
        final long GB = 1024 * 1024 * 1024;
        while (true) {
            OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
            String osJson = JSON.toJSONString(operatingSystemMXBean);
//            System.out.println("osJson is " + osJson);
            JSONObject jsonObject = JSON.parseObject(osJson);
            double processCpuLoad = jsonObject.getDouble("processCpuLoad") * 100;
            double systemCpuLoad = jsonObject.getDouble("systemCpuLoad") * 100;
            Long totalPhysicalMemorySize = jsonObject.getLong("totalPhysicalMemorySize");
            Long freePhysicalMemorySize = jsonObject.getLong("freePhysicalMemorySize");
            double totalMemory = 1.0 * totalPhysicalMemorySize / GB;
            double freeMemory = 1.0 * freePhysicalMemorySize / GB;
            double memoryUseRatio = 1.0 * (totalPhysicalMemorySize - freePhysicalMemorySize) / totalPhysicalMemorySize * 100;

            StringBuilder result = new StringBuilder();
            result.append("系统CPU占用率: ")
                    .append(twoDecimal(systemCpuLoad))
                    .append("%,内存占用率:")
                    .append(twoDecimal(memoryUseRatio))
                    .append("%,系统总内存:")
                    .append(twoDecimal(totalMemory))
                    .append("GB,系统剩余内存:")
                    .append(twoDecimal(freeMemory));
                    //.append("GB,该进程占用CPU:")
                    //.append(twoDecimal(processCpuLoad))
                    //.append("%");
           // System.out.println(result.toString());
            if(((totalMemory - freeMemory)/totalMemory) * 100 > Mem_LOAD_THRESHOLD){
                //内存空余率小于0.7 释放内存
                MenRun = false;
                releaseMemory();
                System.gc();
            }else{
                MenRun = true;
            }
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static double twoDecimal(double doubleValue) {
        BigDecimal bigDecimal = new BigDecimal(doubleValue).setScale(2, RoundingMode.HALF_UP);
        return bigDecimal.doubleValue();
    }

}
  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值