Mat内存泄漏分析

使用 MAT分析内存泄漏 使用 MAT分析内存泄漏 我们前面讲过,我们可以使用 jmap –histo 这种命令去分析哪些对象占据着我们的堆空间。但是那是比较容易分析的问题,如果是遇到内存情况比较复杂 的情况,命令的方式是看不出来的,这个时候我们必须要借助一下工具。当然前提是通过 jmap 命令把整个堆内存的数据 dump 下来。 内存分析工具 VisualVM 这个是上节的那个案例抛出了 OOM 后到处的内存的 dump 日志信息,我们可以导入 VisualVm 属于比较寒酸的工具,基本上跟 jmap 之类的命令没多 阅读详情
AI摘要

本文详细介绍了Java内存泄漏的定义、危害及根源,重点讲解了如何使用MAT工具进行内存泄漏分析,通过实例演示了内存泄漏的排查过程,包括OOM案例模拟和实际知识产权服务案例。强调了及时释放资源的重要性,以及在代码审查中的注意事项。

Mat内存泄漏分析

1、分析背景

1.1、什么是内存泄漏
内存泄漏是我们经常听见的一个词,其定义是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢设置系统崩溃的严重后果。那么在JAVA中也是同样适用的,但是对于JAVA的内存泄漏通常是指堆区域的内存泄漏,因为Java的GC回收机制只是针对堆内存和方法区而言。相信图1-1大家肯定不会陌生,通常来说Java的内存泄漏是指程序在申请内存后,无法释放已经申请的内存空间,无用对象持续占有内存或无用对象的内存得不到及时释放,从而造成内存空间的浪费,内存泄漏的最终结果就是导致OOM(Out Of Memory)。我们可以将内存泄漏视为疾病,将OutOfMemoryError视为症状,但是并非所有的OOM都意味着内存泄漏,也并非是所有的内存泄漏都表现为OOM【1】。
内存泄漏是非常糟糕的事情,因为程序执行期间泄漏的内存块不仅会降低系统的性能,更糟糕的后果是导致JVM crash,甚至是系统的崩溃。因为分配但未使用的内存块必须在系统耗尽空闲物理内存时进行换出。最终,程序甚至可能耗尽其可用的虚拟地址空间。
在这里插入图片描述

图1-1 JVM布局图
1.2、内存泄漏的危害
1.2.1、频繁GC
我们知道JVM的内存管理实际上就是对象的分配和释放问题,在Java中通过关键词new的每个对象申请空间(除开基本类型),所有对象都在Heap中分配空间。而对象的释放是由GC(garbage collection)决定和执行。由于内存的分配和释放都是由程序完成,因此极大的简化了Java程序员的工作,但是却加重了JVM的工作。因为为了正确的释放对象,GC必须监控每一个对象的运行状态,包括对象的申请、引用、被引用和赋值等,GC都需要进行监控。
了解JVM GC的同学肯定听过Minor GC和Full GC,在我们的Eden区不够new新对象的时候就会触发Minor GC,而在老年代剩余空间不足以存放升级到老年代对象的时候就会触发Full GC,或者被设置的HandlePromotionFailure强制执行Full GC。因为不管是什么GC,怎么触发GC的,我们始终要记住一个单词:stop-the-word,该动作会在任何一种GC算法中发生。stop-the-word以为这JVM因为需要执行GC而停止了应用程序的执行,那么频繁的GC必定会使用户感受到明显的卡顿,影响用户的体验。
1.2.2、OOM(Out Of Memory)
前面我们已经说了内存泄漏是病症,OOM是引发的症状,如果说在上面频繁GC的情况下程序还能保证正常的执行,那么在更加糟糕的情况下是GC已经无法清理出更多的空间了,那么对于任何内存资源申请的操作(包括new一个对象)都会导致失败,而且还可能导致维持JVM运行的必要内存大小被吃满,最终导致JVM的Crash(JVM退出不一定导致JVM Crash)。在该种情况下可能会拖累服务器,导致服务器性能降低甚至崩溃。
1.3、谁是“垃圾”
要分析Java的内存泄漏首先要明确我们分析的目标,在刚开始接触Java的时候都听说Java相较于C++由强大的垃圾回收机制,我们申请的对象都不用自己管理,GC会替我们在不需要的时候自动回收该对象的资源。那么GC都是怎么回收的?怎么判断谁是“垃圾”?怎么判断在何时回收?
1.3.1、谁是“垃圾”
目前常用的两种确定谁是“垃圾”的算法有引用计数和根可达性分析算法两种。引用计数算法对于任意都想都记录一个其引用数,当引用数为0的时候就回收该对象的资源,该算法实现简单但是面临着循环引用的问题,如图1-2所示。那么出于该考虑Java采用的是根可达性分析算法实现的GC,如图1-3所示,在JVM中所有对象之间的引用关系会
在这里插入图片描述

图1-2、循环引用示意图
在这里插入图片描述

图1-3、可达性分析示例
组织成一棵引用树,我们可以从根节点对象出发,将所有的可达性节点都打上标记,那么在进行GC的时候我们就将没有标记的对象GC掉。从图1-3也可以看出可达性分析算法可以有效的解决循环引用的“垃圾”,也能有效的解决普通的无用对象。
1.3.2、如何产生的内存泄漏
既然素质教育(GC)这么优秀,谁是“垃圾”一下就找出来了,然后直接给回炉重造,那么为什么还会有漏网之鱼呢(就像我们这些素质教育的漏网之鱼)?其实问题就出现在我们程序猿本身,如图1-3所示,假设我们有的人想当海王(我就不念身份证了),O对象明明不需要M对象或者只是在最开始的地方需要使用一下,但是它却偏偏要引用着对象M,吊着别人然后又不和别人在一起。那么这个蜜汁操作就会迷惑到我们的GC,它就认为对象M和对象N是可达的,那么就不会对其进行回收,久而久之就造成了对象积压,内存的泄漏。当然上面说的只是一种例子,有得对象长期持有不需要或者明明只需要短期使用的对象不释放,如图1-4[2,3]展示了常见的内存泄漏。
在这里插入图片描述

图1-4、常见内存泄
下面是就上图中的某些内存泄漏的解释:
a)、静态集合类,如将HashMap和ArrayList等申请成静态变量,那么它们将与程序结拜,不求同年同月同日生,但是肯定会同年同月死。那么容器中的所有对象都跟着不能被释放,从而导致内存的泄漏。(长生命周期持有短生命周期的引用)。
b)、各种连接,如数据库连接,网络连接,IO连接等,如果没有显示的调用关闭函数,那么会导致大量的对象无法被回收,从而引起内存的泄漏。
c)、变量的作用与大于本身的使用范围。
d)、改变hash值,因为修改了hash的字段,导致无法找到之前存储的对象引用,无法回收。
e)、过期引用未及时清空。
f)、缓存泄漏,当对象被引入缓存的时候忘记清除。
g)、内部非静态类,内部非静态类默认持有外部类的强引用,因此当内部类被长期饮用的时候,外部类对象将无法回收。

2、如何排查内存泄漏

2.1、工具
使用强大的工具进行内存泄漏的分析是必不可少的,我们不可能逐行代码的查看哪里产生了内存泄漏,也不可能从海量的日志文件中快速定位内存泄漏的位置,下面我将介绍几种内存泄漏的分析工具。
a)、JProfiler,JProfiler 是一个商业授权的 Java剖析工具,用于分析Java EE和Java SE应用程序,IDEA上面有对应的插件。JProfiler是一款非常强大的Java性能分析工具,不仅可以监控Java的内存使用情况,还可以监控CPU负载、实时内存、线程运行情况等,并且具备友好的可视化界面,JProfiler操作界面展示[4]。
b)、jconsole,jconsole是从Java5引入的内置性能分析器,可以从命令行或在HUI shell中运行,操作简单,有可视化界面相对而言比较友好(虽然不是很精致)[5]。
c)、Java visualVM,Java visualVM也是JDK自带的性能分析工具,其集成了多个 JDK 命令行工具的可视化工具,可以提供强大的分析能力,对 Java 应用程序做性能分析和调优[6]。
d)、JRockit,需要使用的JVM是JRockitVM才行,虽然功能还不错,但是已经很少被使用了。
e)、MAT(memory Analyzer tool),MAT是一款非常强大的内存分析工具,在Eclipse中有相应的插件,同时也有单独的安装包。在进行内存分析时,只要获得了反映当前设备内存映像的hprof文件,通过MAT打开就可以直观地看到当前的内存信息。MAT包含强大的统计功能,可以将内存中对象、类、堆栈、GCRoot到对象的引用路径和线程信息等统计归纳并用可视化的方式呈现在我们面前,这样,整个内存信息就一览无余地显示在了我们的面前[7]。
2.2、MAT使用
2.2.1、MAT安装
MAT的安装可以参考下面的文章:MAT安装教程
2.2.2、hprof和dump文件
MAT能打开的文件包括hprof文件(Java内存镜像文件,其中包含了内存堆栈的详细使用信息)和dump文件,hprof文件我们可以在启动程序的命令行中添加运行参数:
-XX:OnOutOfMemoryError=/bin/kill -9 %p
-Djava.io.tmpdir=/your_application/var/tmp
只要添加了上面的两个参数,当有OOM异常出现的时候,JVM就会将当前的虚拟机的堆栈信息以及内存中对象的信息放入hprof文件中,名字是大概java_pid加上进程号,比如:java_pid11656.hprof。dump文件是进程的内存镜像,可以把程序的执行状态、堆栈信息和对象的信息通过调试器保存到dump文件中,可以使用jmap命令导出dump文件,命令示例:
jmap -dump:live,format=b,file=xxxx.bin 进程ID
2.2.3、MAT基础使用
利用上面的方式我们可以获取到hprof和dump文件,那么我们现在可以通过MAT将文件导入,首先按照图2-1打开文件,如果是dump文件记得在打开文件的时候选择打开文件的种类为All Files。
在这里插入图片描述

图2-1、如何打开hprof和dump文件
用MAT打开一个hprof文件后一般会进入如图2-1的overview界面,或者和这个界面类似的leak suspect界面,overview界面会以饼图的方式显示当前消耗内存最多的几类对象,可以使我们对当前内存消耗有一个直观的印象。但是,除非你的程序内存泄漏特别明显或者你正好在生成hprof文件之前复现了程序的内存泄漏场景,你才可能通过这个界面猜到程序出问题的地方。如图2-1所示肯定出现了问题,有个对象占据了1.5G的内存空间!下面我们来看看MAT的其他基本功能如,图2-3所示,其可以用不同的统计图和不同的维度展示堆栈的使用情况。
在这里插入图片描述

图2-2、MAT的Overview界面
在这里插入图片描述

图2-3、MAT主界面基本功能
在展示后续功能的时候需要掌握两个基本概念,shallo heap和retained heap,其实简单来说就是前者是对象自己占据的存储空间,而后者是对象及其引用的对象占据的空间总和(其实不太正确这么说,但是基本上是这个意思,除了图2-4所示的情况),那么当该对象被回收的时候retained heap就是我们能够回收到的空间,MAT是通过分析引用树实现的retained heap的计算。图2-4展示了一棵引用树,我们现在来计算对象C的retained heap,那么应该是包含对象D、F、E、G、H,因此retained heap就是C加上这些对象,但是如果我们的C不指向D,那么retained heap就是:E、G,特别注意没有H。
在这里插入图片描述

图2-4 特殊的retained heap案例
在这里插入图片描述

图2-5 Histogram功能展示
图2-5展示了Histogram界面显示的信息,其中包含了对象数量,shallow heap和retained heap,除此之外我们如果双击某个类还能展现出额外的功能,List Object可以展示引用和被引用的情况,Merge shortest Paths to GC Roots可以展示对象到GC Root的最短路径,可以用于帮助我们发现聚集的垃圾对象即内存泄漏的地方。树状结构的界面展示和使用类似Histogram,在此就不赘述了。OQL的学习可以参考如下的博客:MAT基础使用教程。

3、利用Mat实现内存泄漏分析

3.1、OOM案例模拟
图2-3展示了有个功能是内存泄漏分析,那么到底是怎么分析的?下面我们来看一个实际案例,我们将IDEA的堆内存调成64MB,然后让OOM的时候自动导出内存的快照,可以在IDEA中添加如图3-1的参数:
-Xmx64m:修改堆的最大内存为64M
-XX:+HeapDumpOnOutOfMemoryError:出现OOM的时候自动生成dump文件
在这里插入图片描述

图3-1 IDEA模拟OOM的准备工作
然后我们写一段劣质代码来撑爆内存:
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class OOMTest {
public static void main(String[] args) {
oom();
}

private static void oom(){
    Map<String,Pilot> map = new HashMap<>();
    Object[] array = new Object[1000000];
    for(int i = 0;i < 1000000;i++){
        String d = new Date().toString();
        Pilot p = new Pilot(d,i);
        map.put(i+"_RuanCong",p);
        array[i] = p;
    }
}

}

运行这段程序一会就能看见OOM错误,在左侧就可以看见dump出来的dump文件,随后我们用MAT打开,可以看见下面的Problem Suspect分析,其可以明确的指出在哪个线程的哪个变量持有了多大的内存,是被哪个加载器加载的,然后还可以点击detail显示具体的对象泄漏情况,
在这里插入图片描述

图3-2 OOM的内存泄漏分析报告
在这里插入图片描述

图3-3 OOM的detail
从图3-4中可以很轻松的看出来,在线程java.lang.Thread @ 0x7bdbc4a30 main中有个HashMap对象的shallow heap和Retained Heap完全不成比例,这时候我们就要思考了,这个hashMap肯定是长期存在并且持有了大量的对象,导致大量的对象得不到释放,从而造成的内存泄漏,然后我们再回头看代码确实也是这样,当然这只是一个简单的流程分析示例,在实际的场景中会遇见比这个复杂很多的案例,下面我们来分析一个实际案例。
3.2、知识产权服务内存泄漏实际案例分析
case是分析知识产权服务是否存在内存泄漏,首先从服务器下载堆栈快照dump文件到本地,然后将dump文件倒入MAT进行分析,可得到如图3-4所示的Overview界面:
在这里插入图片描述

图3-4 0728dump文件分析Overview展示
其实从这个饼图我们就能看见有个超级大的对象,正常是不可能有这么大的对象(毕竟足足占据了1.5G),我们先点击泄漏分析,看看泄漏的报告是什么。点击detail后可以获取到如图3-5的界面,从描述来看我们可以定位到org.apache.http.impl.conn.PoolingClientConnectionManager类对象被大量持有,接着看下面的
Common Path To the Accumulation Point(到达聚集点的路径),我们可以看出这个聚集对象是存储在一个ArrayList中的,因此初步怀疑是有人在不停的new对象然后add到了ArrayList中,但是ArrayList生命周期肯定很长,导致短期的org.apache.http.impl.conn.PoolingClientConnectionManager对象没有及时释放导致的内存泄漏,因为正常是不可能出现这么大的list。
在这里插入图片描述

3-5 leak suspects界面
然后是问强哥确定是哪个服务,拉去下来进行代码的分析,直接根据关键类com.aliyun.oss.common.comm.IdleConnectionReaper 全局搜索,然后定位到该类如图3-6所示,其中果然有个ClientConnectionManager的ArrayList,然后再继续往自己的代码定位,直接用IDEA的find usages发现没有直接引用的代码,那么我们直接看我们自己的哪些代码中包含了这个类所在的jar包。
在这里插入图片描述

图3-6 IdleConnectionReaper类
搜索的时候如图3-7所示,直接搜索使用这个包的地方,从最长的名字开始搜索,没有就少搜索一个层级,最后是在com.aliyun.oss搜索到了我么你自己的业务类OssProxy。整个业务类不是很复杂,我就把整个代码贴上来。
在这里插入图片描述

图3-7 定位引用该包的业务类
package com.jindidata.cloud.intellectual.property.proxy;

// 直接通过使用的这两个类定位问题
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.OSSObject;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

@Service
@Slf4j
public class OssProxy {
private static final String endpoint = “http://oss-cn-beijing.aliyuncs.com”;

private static final String accessKeyId = "LTAI4FhGuYSS7TFQZmXuMWue";

private static final String secretAccessKey = "4rOxVxfOa88GxgYyosPZ1ejtkmrNvJ";

private static final String bucketName = "jindi-oss-wangsu";

/**
 * 读取oss中内容
 *
 * @param key
 * @author lfy
 * @date 2021-07-07 18:14
 */
public String getContent(String key) {
    if (StringUtils.isBlank(key)){
        return null;
    }
    // 每次new了需要释放资源才行
    OSSClient ossClient = new OSSClient(endpoint, accessKeyId, secretAccessKey);
    if (!OSSClient.doesObjectExist(bucketName, key)) {
        // 知道这里就发现了个内存泄漏点,return前ossClient没有释放连接!!
        return null;
    }
    OSSObject ossObject = ossClient.getObject(bucketName, key);
    BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent()));
    StringBuilder sb = new StringBuilder();
    try {
        while (true) {
            String line = reader.readLine();
            if (line == null) {
                break;
            }
                            sb.append(line);
        }
        String oriStr = sb.toString();
        if (oriStr.length() >= 2 && oriStr.startsWith("\"")){
            oriStr = oriStr.substring(1);
        }
        if (oriStr.length() >= 2 && oriStr.endsWith("\"")) {
            oriStr = oriStr.substring(0, oriStr.length()-1);
        }
        if (StringUtils.isBlank(key)) {
            return null;
        }
        oriStr = oriStr.replaceAll("\\\\s","")
                .replaceAll("\\\\n", "")
                .replaceAll("\\\\", "");
        return oriStr;
    } catch (IOException e) {
                    log.error("OssProxy.getContent oss,key={},error", key, e);
    } finally {
        try {
            // 内存泄漏点2,直接是用完了ossClient没有释放连接!!
                            reader.close();
        } catch (IOException e) {
                            log.error("OssProxy,getContent oss,key={},error", key, e);
        }
    }
    return null;
}

}

    至此有很大概率怀疑是这里出现了问题,为了严谨起见,我查阅了OSS的官方文档【8】:OSS官方文档, 发现在官方文档中别人说了在使用资源后需要显式的释放资源,调用shutdown()函数实现,那么至此确定出来了内存泄漏的具体位置,就在于这个链接的地方,然后利用IDEA的annote就可以看出是哪个小伙伴写的内存泄漏了(哈哈哈,犯罪侠现场)。为了搜集证据,我们继续深入源代码会发现我们的OSSClient每次在new的时候都会注册到IdleConnectionReaper类中,并且加入ArrayList,该类是一个独立的线程,但是只有在调用了Shutdown函数的时候添加进入的ClientConnectionManager才会从arrayList中删除,否则就会一直被持有,那么最后久而久之就会造成内存泄漏。因为跟踪源代码发现OSSClient底层是封装的httpClient,虽然这个客户端会超时释放,但是OSSclient还持有很多其他的资源,并没有超时释放的操作。

4、总结

    上面的实际案例最终的原因分析其实就是资源的使用完成之后没有被释放,其实除了OSSClient还有数据库连接、IO链接、网络连接我们使用完成之后都要记得及时释放,还有个陷进就是我们创建成功后,哪怕进行了某些判空的操作提前返回了,在返回之前一定记得要释放资源!!!!还有就是使用集合的时候记得及时释放已经使用过并且使用不到的资源,下面用一个实际案例说明,看看你能不能发现问题:

import java.util.Arrays;

public class Stack {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;

public Stack() {
    elements = new Object[DEFAULT_INITIAL_CAPACITY];
}

public void push(Object e) {
    ensureCapacity();
    elements[size++] = e;
}

public Object pop() {
    if (size == 0)
        throw new EmptyStackException();
    return elements[--size];
}

private void ensureCapacity() {
    if (elements.length == size)
        elements = Arrays.copyOf(elements, 2 * size + 1);
}

}

5、参考文献
【1】、 什么是内存泄漏
【2】、 Notzuonotdied–内存泄漏分类–优快云
【3】、ratelfu–Java中内存泄漏8种情况的总结
【4】、Java性能分析工具–JProfiler
【5】、Java性能分析工具–JConsole
【6】、Java性能分析工具–VisualVM
【7】、利用MAT进行内存泄漏分析
【8】、OSS官方操作文档

MAT工具定位分析Java堆内存泄漏问题方法 MAT,全称Memory Analysis Tools,是一款分析Java堆内存的工具,可以快速定位到堆内泄漏问题。该工具提供了两种使用方式,一种是插件版,可以安装到Eclipse使用,另一种是独立版,可以直接解压使用。 阅读详情

相关推荐

一文深度讲解JVM 内存分析工具 MAT及实践(建议收藏)

1. 前言熟练掌握 MAT 是 Java 高手的必备能力,但实践时大家往往需面对众多功能,眼花缭乱不知如何下手,小编也没有找到一篇完善的教学素材,所以整理本文帮大家系统掌握 MAT 分析工具。本文详细讲解 MAT 众多内存分析工具功能,这些功能组合使用异常强大,熟练使用几乎可以解决所有的堆内存离线分析的问题。我们将功能划分为4类:内存分布详情、对象间依赖、对象状态详情、按条件检索。每大类有多个功能点,本文会逐一讲解各功能的场景及用法。此外,添加了原创或引用案例加强理解和掌握。如图所示:​编辑切换为居中添加图

m0_63437643的博客 1万+

玩转 MAT 分析内存泄漏

MAT 工具是基于 Eclipse 平台开发的,本身是一个 Java 程序,是一款很好的内存分析工具,所以如果你的堆快照比较大的话,则需要一台内存比较大的分析机器,并给 MAT 本身加大初始内存,这个可以修改安装目录中的 MemoryAnalyzer.ini 文件。可以看到,上手 MAT 工具是有一定门槛的,除了其操作模式,还需要对我们前面介绍的理论知识有深入的理解,比如 GC Roots、各种引用级别等。如果不能通过大对象发现问题,则需要对快照进行深入分析。

AlbenXie的博客 2079

模拟内存泄漏并MAT分析

记录一次如何通过MAT工具定位内存泄漏点 一、准备可以引起内存泄漏的代码OutOfMemoryGCLimitExceed.java import java.util.HashMap; import java.util.Map; import java.util.Random; public class OutOfMemoryGCLimitExceed { public static void addRandomDataToMap() { Map<Integer, S.

myccode的专栏 615

【生产问题排查 二】一次内存泄露排查-MAT使用指南

照例总结一下,线上出了问题不要慌,也别想着保留现场,先止损!平时的报警机制要建立好且阈值要低些,这样才能先于业务发现并解决问题。还有就是MAT是真香!

MaoLin Tian's Blog 3718

Eclipse MAT分析内存泄漏

选择 "Merge Shortest Paths to GC Roots" → "exclude all Phantom/Weak/Soft etc. references"选择 "Show Objects in Collection" 或 "Inspect Collection"在你的截图中,点击右上角的 "Modify options" 按钮(或者按 Alt+M)。在 "VM options" 或 "Common VM Arguments" 字段中填写。

卷不动了,你们继续卷。 432

通过MAT分析内存泄漏

获得dump文件 通过命令jmap -dump:live,format=b,file=***.hprof pid eg:jmap -dump:live,format=b,file=dump.hprof 48671 shell启动脚本增加如下配置: 2.1. -XX: HeapDumpOnOutOfMemoryError 当OutOfMemoryError发生时自动生成 Heap Dump ...

牧夏的个人博客 3345

Eclipse Memory Analyzer tool(MAT)分析内存泄露(二)

Eclipse Memory Analyzer tool(MAT)分析内存泄露(二)

shog808的博客 2843

MAT内存分析工具实战指南:深入解析Java内存泄漏

本文还有配套的精品资源,点击获取 简介:MAT(Memory Analyzer Tool)是一款由Oracle提供的Java内存泄漏分析工具,适用于Windows平台。它通过直观的界面和多种分析功能,帮助开发者识别和解决Java应用中的内存泄漏问题。MAT提供对象概述、dominator tree、内存泄漏嫌疑报告、对象比较、碎片分析和自定义分析等核心功能,使内存泄漏排查更...

weixin_35705784的博客 3544

利用MAT进行内存泄漏分析

前言 对于程序员来说码代码容易,保证代码的稳定性很难。有时候写完一个功能可能只需要一天时间,但是这个功能隐藏的bug导致的线上问题排查可能需要一周或者更长时间。因此,拥有良好的代码结构和编码规范是一个程序员应该长期坚持并为之奋斗的一个目标。但是,百密也难免一疏,没有百分之百没有问题的代码,在产品上线前,我们需要对自己的代码进行充分的自测,发现问题解决问题,保证自己产品的稳定性并减少对用户的

大雀儿飞飞的专栏 4万+

Java内存泄漏分析利器:MAT工具实战解析

int i = 0;0,cl,null// 极简的.class字节码(仅包含基本结构)逻辑分析:- 使用绕过类加载机制直接注册类。- 每次循环创建新的ClassLoader和类名,避免重复定义。- 类元数据持续累积于Metaspace中,无法被回收。JVM参数控制:设置元空间上限为64MB,加速复现问题。参数作用初始元空间大小最大元空间大小(默认无限制)输出GC详情,观察Metaspace使用情况。

weixin_33308579的博客 814

Jlink除了调试还能干啥?用JFlash SPI给W25Q64烧录固件的5个实用技巧

本文深入探讨了Jlink的隐藏功能,特别是通过JFlash SPI高效烧录W25Q64的5个进阶技巧。从硬件连接优化到批量处理脚本,再到数据安全验证,这些技巧能显著提升烧录速度和稳定性,适用于量产环境。文章还提供了详细的参数配置和脚本示例,帮助工程师充分发挥Jlink的潜力。

weixin_29164843的博客 409

利用MAT工具分析内存泄漏

我们可以使用 jmap –histo 这种命令去分析哪些对象占据着我们的堆空间。但是那是比较容易分析的问题,如果是遇到内存情况比较复杂 的情况,命令的方式是看不出来的,这个时候我们必须要借助一下工具。当然前提是通过 jmap 命令把整个堆内存的数据 dump 下来。包括jdk自带的内存分析工具VisualVM,分析的数据非常有限。 MAT 简介 MAT 工具是基于 Eclipse 平台开发的,本身是一个 Java 程序,是一款很好的内存分析工具,所以如果你的堆快照比较大的话,则需要一台内存比较大的分析机器,

bug_come的博客 1406

车规级非易失存储选型指南:从AEC-Q100到ISO 26262的可靠性设计

非易失存储器是电子系统中负责长期保存关键数据与代码的核心组件,其可靠性直接决定了系统的长期稳定运行能力。在汽车电子领域,这一要求被提升到了极致,必须满足严苛的车规级标准。从原理上看,存储器的数据保持能力、擦写寿命等关键参数在高温、振动等恶劣环境下会急剧衰减,因此需要专门的设计与验证。其技术价值在于保障车辆全生命周期的功能安全与数据完整性,避免因存储失效导致的安全隐患或频繁维护。应用场景涵盖从发动机控制单元、自动驾驶域控制器到智能座舱的各类电子控制单元。本文聚焦于车规级非易失存储的选型,深入解析AEC-Q10

weixin_30938149的博客 458

android内存泄漏MAT,Android内存泄漏分析(MAT)

本文是使用Eclipse Memory Analyzer Tool (MAT)进行内存泄漏分析的笔记。遇到大大小小的内存泄漏,都可以通过MAT分析出来。安装To install the Memory Analyzer into an Eclipse IDE use the update site URL provided below. The Memory Analyzer (Chart) fea...

weixin_31751887的博客 415

ICC 实战解析——CTS 时钟树综合中的关键设置与优化策略

本文深入解析ICC工具中CTS时钟树综合的关键设置与优化策略,涵盖时钟树异常引脚设置、目标参数配置、非默认布线规则(NDR)等核心技术。通过实战案例展示如何有效控制时钟偏差、优化信号完整性,并平衡功耗与面积,为芯片物理设计提供专业指导。

weixin_30872577的博客 325

聚类模型-层次聚类

聚类模型 1、层次聚类 2、原型聚类-K-means 3、模型聚类-GMM 4、EM算法-LDA主题模型 5、密度聚类-DBSCAN 6、图聚类-谱聚类 一、层次聚类 一、聚类理论 ​ 一般来说,聚类是在训练样本的标签信息不知的情况下,学习样本内在的性质和规律,将有限的集合划分成ccc类。根据“方以类聚,物以群分”的思想,类内对象尽可能的相似,...

myazi 6504

Android 性能优化之MAT分析内存泄漏

http://www.iconfont.cn/ https://icomoon.io/app/#/select https://github.com/mikepenz/Android-Iconics http://mp.weixin.qq.com/s?__biz=MzAxMTI4MTkwNQ==&mid=2650821086&idx=1&sn=080bc2cfaa04947b974bf6273bbd

寒江蓑笠的专栏 798

深入理解 DDR5 Bank Group 与并行调度机制

Bank Group架构和并行调度机制,是DDR5性能跃升的核心秘密!理解它们才能写出高效调度程序,设计出性能强劲又稳定的DDR5系统。🎯记住:Bank Group不是简单的分组,而是高速并行的“魔法钥匙”,巧用它,你的DDR5设计将爆发惊人性能!

weixin_43199439的博客 313

MAT 分析内存泄漏

比较容易分析的问题,我们可以使用jmap -histo这种命令去分析哪些对象占据着我们的堆空间,如果是遇到内存情况比较复杂的情况,命令的方式是看不出来的,这时我们就须要借助一下工具,前提是通过jmap命令把整个堆内存的数据dump下来。 内存分析工具 VisualVM 导入dump日志 package ex13; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import java.u

*King*的博客 450

18、Excel VBA编程:自定义函数创建与代码调试全攻略

本文详细介绍了Excel VBA中自定义函数的创建方法,以获取单元格注释为例演示了完整开发流程,并深入讲解了代码调试的重要性与核心工具。内容涵盖三种主要错误类型及其应对策略,系统介绍了调试工具栏、断点、逐行执行、Locals窗口、Immediate窗口等实用功能。通过综合案例展示了如何运用调试技术解决实际问题,并总结了提前规划、逐步测试、日志记录等最佳实践,帮助读者提升VBA编程效率与代码质量。

life6的博客 100

Python学习第32天:Web前端入门

本文介绍了Web前端开发三大核心技术:HTML、CSS和JavaScript。首先概述了HTML的发展历程和HTML5新特性,详细讲解了常用HTML标签如文本、列表、链接、图像、表格、表单等。其次介绍了CSS的基础语法、选择器、颜色字体设置、盒子模型和布局定位方法。最后简要提及JavaScript为网页添加交互功能的作用。文章为Python开发者提供了前端技术的基础知识,帮助理解网页的结构、样式和行为实现原理。

tigerhhzz的博客 1911

MAT内存泄漏分析工具

MAT是一款强大的内存泄漏分析工具,MAT不需要安装,下载解压就能用,下载地址 点击打开链接 1.下面模拟一下内存泄漏 private static TextView sTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedI

DoIt的博客 567

使用 MATLAB/Simulink + Simscape Electrical + SimPowerSystems + Stateflow,构建一个多能互补微电网系统的动态响应仿真模型

本文详细介绍了使用MATLAB/Simulink构建多能互补微电网动态响应仿真模型的方法。文章从系统架构设计入手,包含光伏、风电、柴油发电机、锂电池储能等多种组件,重点讲解了建模过程、控制策略(下垂控制、PLL、SOC管理)和模式切换逻辑(Stateflow)。通过四种典型场景(负荷突增、光伏出力骤降、并网/孤岛切换、电动机启动)的仿真分析,验证了微电网在动态响应中的关键性能指标,并提出了高可靠性设计建议。该模型为微电网的稳定性分析和优化设计提供了有效工具,特别强调了储能系统在快速功率支撑中的重要作用。

amy_mhd的博客 160

玩转MAT分析内存泄漏

MAT 简介 MAT 工具是基于 Eclipse 平台开发的,本身是一个 Java 程序,是一款很好的内存分析工具,所以如果你的堆快照比较大的话,则需要一台内存比较大的分析机器,并给 MAT 本身加大初始内存,这个可以修改安装目录中的 MemoryAnalyzer.ini 文件。 柱状图 在柱状图中,我们看到,其实它显示的东西跟 jmap –histo 非常相似的,也就是类、实例、空间大小。 但是 MAT 有一个专业的概念,这个可以显示对象的引入和对象的引出。 在 Eclipse MAT 中,当右键单

u012781820的博客 1941

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Memory Analyzer (MAT)Android内存泄漏分析,快速定位

Memory Analyzer (MAT)Android内存泄漏分析,快速定位 专注于Android开发,分享经验总结,欢迎加入 准备工具 Android Studio Memory Analyzer (MAT) 下载Memory Analyzer (MAT) https://www.eclipse.org/mat/ 在导出的文件夹下打开命令行窗口,输入hprof-conv -z ...

他晓 1万+

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

上一篇: java代码开发规范
下一篇: GC垃圾回收器
Diaos Coder
博客等级 码龄9年 9粉丝 10原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值