实际中进行GC调整

孤立的垃圾车 调优垃圾回收与任何其他性能调优活动没有什么不同。

您需要确保了解当前的情况和期望的结果,而不是因为对应用程序的随机部分进行调整而产生了诱惑。 通常,只需执行以下过程即可:

  1. 陈述您的绩效目标
  2. 运行测试
  3. 测量
  4. 与目标比较
  5. 进行更改并返回运行测试

重要的是,可以设定和衡量目标的三个维度都与性能调整有关。 这些目标包括延迟,吞吐量和容量,理解,我建议您阅读垃圾收集手册中的相应章节。

让我们看看我们如何开始研究设定和实现这些目标的实际情况。 为此,让我们看一个示例代码:

//imports skipped for brevity
public class Producer implements Runnable {

  private static ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2);

  private Deque<byte[]> deque;
  private int objectSize;
  private int queueSize;

  public Producer(int objectSize, int ttl) {
    this.deque = new ArrayDeque<byte[]>();
    this.objectSize = objectSize;
    this.queueSize = ttl * 1000;
  }

  @Override
  public void run() {
    for (int i = 0; i < 100; i++) {
      deque.add(new byte[objectSize]);
      if (deque.size() > queueSize) {
        deque.poll();
      }
    }
  }

  public static void main(String[] args) throws InterruptedException {
    executorService.scheduleAtFixedRate(new Producer(200 * 1024 * 1024 / 1000, 5), 0, 100, TimeUnit.MILLISECONDS);
    executorService.scheduleAtFixedRate(new Producer(50 * 1024 * 1024 / 1000, 120), 0, 100, TimeUnit.MILLISECONDS);
    TimeUnit.MINUTES.sleep(10);
    executorService.shutdownNow();
  }
}

该代码将提交两个作业,每100毫秒运行一次。 每个作业都模拟具有特定寿命的对象:它创建对象,让它们离开预定的时间,然后忘记它们,从而使GC回收内存。

在使用以下参数打开GC日志记录的情况下运行示例时

-XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps

我们开始立即在日志文件中看到GC的影响,类似于以下内容:

2015-06-04T13:34:16.119-0200: 1.723: [GC (Allocation Failure) [PSYoungGen: 114016K->73191K(234496K)] 421540K->421269K(745984K), 0.0858176 secs] [Times: user=0.04 sys=0.06, real=0.09 secs] 
2015-06-04T13:34:16.738-0200: 2.342: [GC (Allocation Failure) [PSYoungGen: 234462K->93677K(254976K)] 582540K->593275K(766464K), 0.2357086 secs] [Times: user=0.11 sys=0.14, real=0.24 secs] 
2015-06-04T13:34:16.974-0200: 2.578: [Full GC (Ergonomics) [PSYoungGen: 93677K->70109K(254976K)] [ParOldGen: 499597K->511230K(761856K)] 593275K->581339K(1016832K), [Metaspace: 2936K->2936K(1056768K)], 0.0713174 secs] [Times: user=0.21 sys=0.02, real=0.07 secs]

根据日志中的信息,我们可以着眼于三个不同的目标来改善情况

  1. 确保最坏情况下的GC暂停不超过预定阈值
  2. 确保停止应用程序线程的总时间不超过预定阈值
  3. 降低基础架构成本,同时确保我们仍然可以实现合理的延迟和/或吞吐量目标。

为此,上面的代码在三种不同的配置上运行了10分钟,导致下表总结了三种截然不同的结果:

GC算法 有用的工作 最长的停顿
-Xmx12g -XX:+ UseConcMarkSweepGC 89.8% 560毫秒
-Xmx12g -XX:+ UseParallelGC 91.5% 1,104毫秒
-Xmx8g -XX:+ UseConcMarkSweepGC 66.3% 1,610毫秒


实验使用不同的GC算法和不同的堆大小运行相同的代码,以测量有关延迟和吞吐量的垃圾收集暂停的持续时间。 有关实验的详细信息和结果的解释,请参见《 垃圾收集手册》 。 请看一下手册中的示例,了解配置的简单更改如何使示例在延迟,容量吞吐量方面完全不同。

请注意,为了使示例尽可能简单,仅更改了有限数量的输入参数,例如,实验未在不同数量的内核或不同的堆布局上进行测试。

翻译自: https://www.javacodegeeks.com/2015/06/gc-tuning-in-practice.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值