引起一致 GC 流失的技术

2023-11-27

我正在寻找基准测试,同时应对大量正在进行的垃圾收集。我之前已经对其在稳定的单线程运行中的行为进行了基准测试,现在我想在压力更大的 JVM 中进行相同的测试;本质上,我希望后台线程以相当一致的速度创建和销毁对象。

我正在寻找有关如何实现稳定但 GC 密集型操作的建议。它需要实现几个目标:

  • 在 GC 上花费相当多的时间(例如 20-50%)
  • 随着时间的推移,执行大致一致的工作量,并为 GC 创建类似一致的工作量
  • 避免淹没堆并触发Java heap space error
  • 避免 GC 过载并触发GC overhead limit exceeded error

我在一些可能导致稳定数量的垃圾收集的事情上实现了自己的通行证。完整的代码可以在这里找到:https://gist.github.com/dimo414/5243162

重点是这两个方法,它们在给定的实时时间内(而不是线程时间或 CPU 时间)构造和释放大量对象:

/**
 * Loops over a map of lists, adding and removing elements rapidly
 * in order to cause GC, for runFor seconds, or until the thread is
 * terminated.
 */
@Override
public void run() {
    HashMap<String,ArrayList<String>> map = new HashMap<>();

    long stop = System.currentTimeMillis() + 1000l * runFor;
    while(runFor == 0 || System.currentTimeMillis() < stop) {
        churn(map);
    }
}

/**
 * Three steps to churn the garbage collector:
 *   1. Remove churn% of keys from the map
 *   2. Remove churn% of strings from the lists in the map
 *      Fill lists back up to size
 *   3. Fill map back up to size
 * @param map
 */
protected void churn(Map<String,ArrayList<String>> map) {
    removeKeys(map);
    churnValues(map);
    addKeys(map);
}

类实现Runnable这样你就可以在它自己的后台线程中启动它(或同时启动多个)。只要您指定,它就会运行,或者如果您愿意,可以将其作为守护线程启动(因此它不会阻止 JVM 终止)并指定它永远运行0秒作为构造函数参数。


我对此类进行了一些基准测试,发现它花费了近三分之一的时间进行阻塞(大概是在 GC 上),并确定了大约 15-25% 的流失率和约 500 的大小的最佳值。每次运行完成 60 秒,下图绘制了线程时间,如java.lang.managment.ThreadMXBean.getThreadCpuTime()以及线程分配的总字节数,如报告所示com.sun.management.ThreadMXBean.getThreadAllocatedBytes().

Churn Percentage benchmark

控制(0% 流失)本质上不应该引入任何 GC,我们可以看到它几乎不分配任何对象,并且几乎 100% 的时间都花在线程中。从 5% 到 95% 的流失率,我们相当一致地看到大约三分之二的时间花在线程上,大概另外三分之一花在 GC 上。我想说,这是一个合理的百分比。有趣的是,在流失百分比非常高的情况下,我们看到线程上花费了更多的时间,大概是因为 GC 进行了如此多的清理,所以它实际上能够更加高效。每个周期搅拌大约 20% 的对象似乎是一个不错的数量。

Data size benchmark

这张图描绘了线程如何在映射和列表的不同目标大小下运行,我们可以看到,随着大小的增加,必须在 GC 上花费更多的时间,有趣的是,我们实际上最终分配了更少的对象,因为较大的数据大小意味着它无法在同一时间段内进行尽可能多的循环。由于我们有兴趣优化 JVM 必须处理的 GC 搅动量,因此我们希望它需要处理尽可能多的对象,并在工作线程中花费尽可能少的时间。因此,4-500 左右似乎是一个不错的目标大小,因为它会生成大量对象并在 GC 上花费大量时间。

所有这些测试都是按照标准完成的java设置,因此使用堆可能会导致不同的行为 - 特别是,~2000 是我在堆填满之前可以设置的最大大小,如果我们增加堆的大小,我们可能会在更大的大小上看到更好的结果堆。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

引起一致 GC 流失的技术 的相关文章

  • SAML 服务提供商 Spring Security

    当使用预先配置的服务提供者元数据时 在 Spring Security 中 是否应该有 2 个用于扩展元数据委托的 bean 定义 一份用于 IDP 元数据 一份用于 SP 元数据
  • OpenCV 中的 Gabor 内核参数

    我必须在我的应用程序中使用 Gabor 过滤器 但我不知道这个 OpenCV 方法参数值 我想对虹膜进行编码 启动 Gabor 过滤器并获取特征 我想对 12 组 Gabor 参数值执行此操作 然后我想计算 Hamming Dystans
  • 比较两个文本文件的最快方法是什么,不将移动的行视为不同

    我有两个文件非常大 每个文件有 50000 行 我需要比较这两个文件并识别更改 然而 问题是如果一条线出现在不同的位置 它不应该显示为不同的 例如 考虑这个文件A txt xxxxx yyyyy zzzzz 文件B txt zzzzz xx
  • JAVA - Xuggler - 组合 MP3 音频文件和 MP4 电影时播放视频

    使用 JAVA 和 Xuggler 以下代码组合 MP3 音频文件和 MP4 电影文件并输出组合的 mp4 文件 我希望在合并音频和视频文件时应自动播放输出视频文件 String inputVideoFilePath in mp4 Stri
  • 运行具有外部依赖项的 Scala 脚本

    我在 Users joe scala lib 下有以下 jar commons codec 1 4 jar httpclient 4 1 1 jar httpcore 4 1 jar commons logging 1 1 1 jar ht
  • 使用 AES SecretKey 的 Java KeyStore setEntry()

    我目前正在 Java 中开发一个密钥处理类 特别是使用 KeyStore 我正在尝试使用 AES 实例生成 SecretKey 然后使用 setEntry 方法将其放入 KeyStore 中 我已经包含了代码的相关部分 The KS Obj
  • 画透明圆,外面填充

    我有一个地图视图 我想在其上画一个圆圈以聚焦于给定区域 但我希望圆圈倒转 也就是说 圆的内部不是被填充 而是透明的 其他所有部分都被填充 请参阅这张图片了解我的意思 http i imgur com zxIMZ png 上半部分显示了我可以
  • 匿名类上的 NotSerializedException

    我有一个用于过滤项目的界面 public interface KeyValFilter extends Serializable public static final long serialVersionUID 7069537470113
  • 以编程方式在java的resources/source文件夹中创建文件?

    我有两个资源文件夹 src 这是我的 java 文件 资源 这是我的资源文件 图像 properties 组织在文件夹 包 中 有没有办法以编程方式在该资源文件夹中添加另一个 properties 文件 我尝试过这样的事情 public s
  • 在游戏视图下添加 admob

    我一直试图将 admob 放在我的游戏视图下 这是我的代码 public class HoodStarGame extends AndroidApplication Override public void onCreate Bundle
  • 如何在 Java 中测试一个类是否正确实现了 Serialized(不仅仅是 Serialized 的实例)

    我正在实现一个可序列化的类 因此它是一个与 RMI 一起使用的值对象 但我需要测试一下 有没有办法轻松做到这一点 澄清 我正在实现该类 因此在类定义中添加 Serialized 很简单 我需要手动序列化 反序列化它以查看它是否有效 我找到了
  • 如何知道抛出了哪个异常

    我正在对我们的代码库进行审查 有很多这样的陈述 try doSomething catch Exception e 但我想要一种方法来知道 doSomething 抛出了哪个异常 在 doSomething 的实现中没有 throw 语句
  • 用于运行可执行文件的python多线程进程

    我正在尝试将一个在 Windows 上运行可执行文件并管理文本输出文件的 python 脚本升级到使用多线程进程的版本 以便我可以利用多个核心 我有四个独立版本的可执行文件 每个线程都知道要访问它们 这部分工作正常 我遇到问题的地方是当它们
  • Eclipse 中 Spring MVC 模型对象的 (jsp /jstl) 视图中的代码辅助

    在 Spring MVC 中 当将对象放置在视图模型中时 如下所示 public String getUser Model model fetch user model addAttribute user user return viewN
  • 具有特定参数的 Spring AOP 切入点

    我需要创建一个我觉得很难描述的方面 所以让我指出一下想法 com x y 包 或任何子包 中的任何方法 一个方法参数是接口 javax portlet PortletRequest 的实现 该方法中可能有更多参数 它们可以是任何顺序 我需要
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • hashcode 的默认实现为以相同方式构造的对象返回不同的值

    我在这里编写一个示例代码 public class Test private int i private int j public Test TODO Auto generated constructor stub public Test
  • Trie 数据结构 - Java [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 是否有任何库或文档 链接提供了在 java 中实现 Trie 数据结构的更多信息 任何帮助都会很棒 Thanks 你可以阅读Java特里树
  • ServletContainer 类未找到异常

    我无法再编译我的球衣项目 并且出现以下异常 GRAVE Servlet Project API threw load exception java lang ClassNotFoundException com sun jersey spi
  • 调整添加的绘制组件的大小和奇怪的摆动行为

    这个问题困扰了我好几天 我正在制作一个特殊的绘画程序 我制作了一个 JPanel 并添加了使用 Paint 方法绘制的自定义 jComponent 问题是 每当我调整窗口大小时 所有添加的组件都会 消失 或者只是不绘制 因此我最终会得到一个

随机推荐