草庐IT

Java G1 : Monitoring for memory leaks in production

coder 2023-08-29 原文

多年来,我们一直使用 +UseParallelOldGC 以适度的堆大小运行 Java 服务。现在,我们开始使用更大的堆和 G1 收集器推出一项新服务。进展顺利。

对于我们使用 +UseParallelOldGC 的服务,我们通过在收集后查看老年代大小并根据阈值发出警报来监控内存泄漏。这非常有效,实际上两周前就拯救了我们的培根。

具体来说,对于 +UseParallelOldGC,我们执行以下操作:

  • ManagementFactory.getMemoryPoolMXBeans()
  • 搜索名称以 "Old Gen" 结尾的 MemoryPoolMXBean 结果
  • 比较 getCollectionUsage().getUsed()(如果可用)与 getMax()

不幸的是,G1 似乎不再有 getCollectionUsage() 的概念。

不过,从根本上说,我们希望在它选择在混合循环或类似的东西中执行的最后一次混合收集之后监视 G1 堆大小。

例如,在 VM 之外,我会对 awk 脚本感到满意,该脚本仅发现最后一个 '(mixed)' 是紧随其后的 '(young)' 并查看最终堆大小是多少(例如,'1540.0M' 'Heap: 3694.5M(9216.0M)->1540.0M(9216.0M)')

有没有办法在 Java VM 中执行此操作?

最佳答案

是的,JVM 为您提供了足够的工具来检索 G1 的此类信息。例如,您可以使用类似此类的类来打印有关垃圾回收的所有详细信息(只需调用 MemoryUtil.startGCMonitor()):

public class MemoryUtil {

    private static final Set<String> heapRegions;

    static {
        heapRegions = ManagementFactory.getMemoryPoolMXBeans().stream()
                .filter(b -> b.getType() == MemoryType.HEAP)
                .map(MemoryPoolMXBean::getName)
                .collect(Collectors.toSet());
    }

    private static NotificationListener gcHandler = (notification, handback) -> {
        if (notification.getType().equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) {
            GarbageCollectionNotificationInfo gcInfo = GarbageCollectionNotificationInfo.from((CompositeData) notification.getUserData());
            Map<String, MemoryUsage> memBefore = gcInfo.getGcInfo().getMemoryUsageBeforeGc();
            Map<String, MemoryUsage> memAfter = gcInfo.getGcInfo().getMemoryUsageAfterGc();
            StringBuilder sb = new StringBuilder(250);
            sb.append("[").append(gcInfo.getGcAction()).append(" / ").append(gcInfo.getGcCause())
                    .append(" / ").append(gcInfo.getGcName()).append(" / (");
            appendMemUsage(sb, memBefore);
            sb.append(") -> (");
            appendMemUsage(sb, memAfter);
            sb.append("), ").append(gcInfo.getGcInfo().getDuration()).append(" ms]");
            System.out.println(sb.toString());
        }
    };

    public static void startGCMonitor() {
        for(GarbageCollectorMXBean mBean: ManagementFactory.getGarbageCollectorMXBeans()) {
            ((NotificationEmitter) mBean).addNotificationListener(gcHandler, null, null);
        }
    }

    public static void stopGCMonitor() {
        for(GarbageCollectorMXBean mBean: ManagementFactory.getGarbageCollectorMXBeans()) {
            try {
                ((NotificationEmitter) mBean).removeNotificationListener(gcHandler);
            } catch(ListenerNotFoundException e) {
                // Do nothing
            }
        }
    }

    private static void appendMemUsage(StringBuilder sb, Map<String, MemoryUsage> memUsage) {
        memUsage.entrySet().forEach((entry) -> {
            if (heapRegions.contains(entry.getKey())) {
                sb.append(entry.getKey()).append(" used=").append(entry.getValue().getUsed() >> 10).append("K; ");
            }
        });
    }
}

在此代码中,gcInfo.getGcAction() 为您提供了足够的信息来将次要集合与主要/混合集合分开。

但是使用您的方法(带有阈值)达到 G1 有一个重要的警告。 G1 中的单个混合回收通常只影响几个老年代区域——足够多以释放足够数量的内存,但不会太多以保持 GC 暂停时间较低。因此,在 G1 中进行混合回收后,您无法确定所有垃圾都已消失。因此,您需要找到更复杂的策略来检测内存泄漏(可能基于收集频率、从多个收集中收集统计信息等)

关于Java G1 : Monitoring for memory leaks in production,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35927926/

有关Java G1 : Monitoring for memory leaks in production的更多相关文章

  1. javascript - ion-content 和 ion-footer 有不同的 $scope - 2

    我的ion-content中有两个输入字段,它们都附加了一个ng-model。然后在我的ion-footer中有一个ng-click,我在其中调用一个函数并传入两个ng-models。当我在ion-content中单击ng-click时,一切正常,但是当我将它移到页脚时,我传递给函数的两个参数未定义。那么这是否意味着ion-content和ion-footer具有不同的$scope?即使它们在同一个文件中并具有相同的Controller?? 最佳答案 我相信ion-footer和ion-content会创建新的子作用域Prototy

  2. javascript - Ion slide box - 如何在 ion slide 中滑动全宽 iframe 视频 - 2

    在我的页面上,我有一个用于图像的ion-slide-box。由于在我的应用程序中用户将能够嵌入视频,因此我还应该将带有视频的iframe添加到同一个slider。这就是我的代码现在的样子:这是我的html:1">这只适用于图像,但是当我有视频时,如果它们占据100%的宽度,我将无法滑动它们,这是我在我的css中设置的,如果它们的宽度小于该宽度,我只能滑动它们如果我只在iframe不占用slider空间的那部分滑动它们。由于我需要让iframe占用100%的宽度,我想知道如何让它工作? 最佳答案 你试过了吗ion-slides相反?i

  3. javascript - angularjs 中的 ui-view 和 ionic 中的 ion-nav-view 有什么区别 - 2

    如您所知,在Angularui-router中,我们使用ui-view将html呈现给父级html。根据this:js文件:$stateProvider.state('report',{views:{'filters':{...templatesand/orcontrollers...},'tabledata':{},'graph':{},}})同样在Ionic框架中我们可以使用这个:有什么区别? 最佳答案 这是自定义Ionic框架指令。您可以在此处找到详细说明ion-nav-view.它具有更多高级功能,如跟踪历史记录、转换等等。

  4. javascript - ionic 2 ion-datetime ISO格式问题 - 2

    我正在使用ion-datetime作为我的预约表格。插入时它工作正常,没有任何问题。但是当我需要从后端更新插入的约会日期表单详细信息时,日期值未显示在ion-datetime中。下面是我的代码:update.html:AppointmentDate:更新.ts:leadDetailsUpdate={appt_date:''};我从后端获取的日期格式如下:appt_date:"2017-01-01"以下是我在控制台中收到的错误消息:解析日期时出错:“null”。请提供有效的ISO8601日期时间格式:https://www.w3.org/TR/NOTE-datetime

  5. javascript - 键盘显示时 Ionic ion-content 不向下滚动 (Android) - 2

    我有一个带有登录表单的简单View。在Android上,如果键盘打开,内容不会向上滚动以防止它位于键盘后面。我按照文档中的键盘说明进行操作,并阅读了很多论坛帖子,但我还没有弄明白。我安装了键盘插件com.ionic.keyboard。这是页面的结构:.....Loginform.....如果我在页面中放置一些额外的虚拟内容,它表明ion-content确实是可滚动的。但是,当通过专注于输入打开键盘时,它不会向上移动。ionic版本?1.0.0-beta.13我的应用程序是全屏的吗?没有我是否测试过键盘插件是否正常工作?是的还有什么需要我做的吗? 最佳答案

  6. xml - 如何在 ion-list angular 2 ionic 2 中显示已解析的 xml 提要数据 - 2

    我得到一个的数组在控制台中,它们每个都包含标题、链接、描述、图像和pubDate,但数据未显示在ion-list中。.你能帮帮我吗?下面是函数load()在rss-service.tsload(){returnObservable.create(s=>{this.http.get('http://url.xml').map(res=>res.text()).subscribe(data=>{if(data){varparser=newDOMParser();varxmlData=parser.parseFromString(data,"application/xml");varitem

  7. javascript - 如何处理 "Go"/"Enter"keyboard button Ionic2 <ion-input> - 2

    处理输入上的“enter”或“go”键盘键的事件是什么?输入不在表单中使用。所以点击它不会“提交”。我只需要事件。(在Beta11上运行android+Ionic2) 最佳答案 我喜欢这样:和:handleLogin(){//Doyourstuffhere} 关于javascript-如何处理"Go"/"Enter"keyboardbuttonIonic2,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  8. php - 使用 Ion Auth 在 Codeigniter 中创建用户角色和配置文件 - 2

    我将Codeigniter与IonAuth一起用于用户管理。我想创建两种不同的用户角色-一种用于志愿者,一种用于组织。我知道我可以将IonAuth的groups用于访问控制之类的事情,但是将字段添加到不同用户类型的好方法是什么(例如-志愿者用户将拥有“口语”'字段,而组织将有一个'任务'字段)?我应该为每个新用户类型扩展IonAuth类并为每种类型单独处理CRUD,还是使用“组”字段和用户ID来引用另一个表中的字段?关于解决这个常见问题的方法有什么见解吗? 最佳答案 我建议只将您需要的所有字段添加到元表中,并且只更新每个用户组所需的

  9. php - Codeigniter ion auth 忘记密码不发送电子邮件 - 2

    如果我提交重置新密码到我的电子邮件,CodeIgniter不会发送邮件。但它会返回一条消息,提示已发送密码重置电子邮件。所以它不会触发错误。我正在使用CodeIgniter2.1.4和IonAuth2.5.2$config['use_ci_email']=TRUE;我已经将此配置设置为TRUE,但仍未发送邮件。 最佳答案 不要更改“ion_auth.php”中的任何内容。文件原样:$config['use_ci_email']=FALSE;//SendEmailusingthebuiltinCIemailclass,iffalsei

  10. javascript - AngularJS + ion-list ng-repeat 不填充列表 - 2

    我正在尝试使用AngularJS和PHP从英特尔XDK中的数据库中使用ng-repeat填充ionic列表。我在阅读了一些问题后进行了一些尝试,但没有任何效果。它填充一个空列表或不显示任何内容。我的代码有什么问题?HTML:NotíciasFotos{{title}}-->{{x.TITLE}}Angular:.controller('temporada2016Ctrl',['$scope','$http',function($scope,$http){$http.get("http://localhost/select-news.php").then(function(respons

随机推荐