java - 如何从 Java 生成大型(1GB)示例 gc 日志文件

标签 java garbage-collection

我需要大型 GC 日志文件来对我的日志分析器应用程序进行基准测试。请建议生成示例 GC 日志文件的最佳方法。

我发现下面这段小代码,每 100 毫秒分配 2MB 内存

class MyTask extends TimerTask{

    static final int MB = 1024 * 1024; //GB= 1024 * 1024 * 1024
    @Override
    public void run() {
        byte[] a1 = new byte[2 * MB];
        a1[1] = 1;
        Runtime runtime = Runtime.getRuntime();
        System.out.print("total :" + (runtime.totalMemory() / 1024)+ " KB\n");
        long free = runtime.freeMemory() / 1024;
        System.out.print("free:" + free+ " KB\n");
    }
}

public class MemoryAllocationTest {
    static public void main(String[] arg){
        Timer timer = new Timer();
        timer.schedule(new MyTask(), 100, 100);
    }
}

现在我可以使用 VM 选项生成 gc 日志文件

-XX:+DisableExplicitGC
-XX:+PrintGCDetails
-XX:+PrintGCApplicationStoppedTime
-XX:+PrintGCApplicationConcurrentTime
-XX:+PrintGCDateStamps
-Xloggc:gclog.log

生成 200-300 Mb 的文件需要几天时间。但我需要 >= 1 GB 文件大小以及不同类型/品种的 gc 事件。

我怎样才能做到这一点?

最佳答案

您可以强制运行java垃圾收集器Runtime

删除-XX:+DisableExplicitGC选项

/**
 * Use less memory, for example jvm options -Xms64m -Xmx64m
 */
public class GarbageGenerator {

    private static String generateGarbage() {
        StringBuilder b = new StringBuilder();
        for (long i = 0; i < 100_000; i++) {
            b.append(Long.valueOf(i));
        }
        return b.toString();
    }

    private static final long MAX = 100_000_000L;
    private static final long TP = 10_000_000L;

    public static void main(String[] args) {
        System.out.println("Garbage generation started");
        // we need more garbage, so not an ArrayList
        final List<String> list = new LinkedList<>();
        long done = 0L;
        long i = 0L;
        final Lock lock = new ReentrantLock();
        int cpuLogicalCores = Runtime.getRuntime().availableProcessors();
        ExecutorService exec = Executors.newFixedThreadPool(cpuLogicalCores);
        do {
            final CountDownLatch countDown = new CountDownLatch(cpuLogicalCores);
            for (int k = 0; k < cpuLogicalCores; k++) {
                exec.execute(() -> {
                    String garbage = generateGarbage();
                    lock.lock();
                    try {
                        list.add(garbage);
                    } finally {
                        lock.unlock();
                    }
                    countDown.countDown();
                });
            }
            try {
                countDown.await();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            list.clear();
            ++i;
            if (0 == (i % TP))
                System.out.println("%" + Long.valueOf(done += 10L));
            // force run gc, check that not disabled by jvm command line options
             Runtime.getRuntime().gc();
        } while (i < MAX);
        exec.shutdown();
        try {
            exec.awaitTermination(365, TimeUnit.DAYS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        System.out.println("Garbage generation end");
    }

}

关于java - 如何从 Java 生成大型(1GB)示例 gc 日志文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49279813/

相关文章:

c# - 应该定期调用 GC.Collect() 吗?

java - Vaadin 7 Servlet ClassCastException 问题

java - 从 2 个笛卡尔坐标确定直线方程

java - 如何在 HashMap 中添加和获取类的对象值

java - E4 EPartService findPart() 抛出 java.lang.Null 指针异常

javascript - 暂时禁用 node.js 垃圾收集

包装多个输出流对象时的 Java 输出流行为

java - Android Studio : Searchview for images, 怎么办?

java - 如何知道 JVM 当前是否正在执行 GC?

python - 在哪里调用 gc.collect()