精华内容
下载资源
问答
  • 内存转储

    千次阅读 2011-11-24 11:27:04
    小内存转储 目录 什么是小内存转储如何设置解决蓝屏故障 ... 内存转储是用于系统崩溃时,...小内存转储,就是只保存内存前64KB的基本空间数据的内存转储文件。这样可以节省磁盘空间,也方便文件的查看。 如何设置

    小内存转储

    什么是小内存转储

      内存转储是用于系统崩溃时,将内存中的数据转储保存在转储文件中,供给有关人员进行排错分析使用,(如果是个人用户,选择 “无”对普通用户来说,一点用处也没有,甚至会导致泄密)。小内存转储,就是只保存内存前64KB的基本空间数据的内存转储文件。这样可以节省磁盘空间,也方便文件的查看。
    如何设置
      右键点击“我的电脑”,选“属性→高级→启动和故障恢复→设置”,打开“启动和故障恢复”选项卡,在“写入调试 信息”下拉列表中选中“小内存转储(64KB)”选项。
      此选项要求在计算机的启动卷上有一个至少 2 MB 的分页文件,并指定每次系统意外停止时 Windows 都创建一个新文件。这些文件的历史记录存储在小转储目录 (%SystemRoot%\Minidump) 下列出的文件夹中。在 Windows XP 和 Windows Server 2003 中,小内存转储文件用于 Windows 错误报告功能。要通过修改注册表指定您希望使用小内存转储文件,请将 CrashDumpEnabled DWORD 值设置为 3。例如,在命令提示符处键入以下信息,然后按 Enter 键:
      wmic recoveros set DebugInfoType = 3
      要通过修改注册表指定您希望使用 D:\Minidump 文件夹作为小转储目录,请将 MinidumpDir 可扩展字符串值设置为 D:\Minidump。例如,在命令提示符处键入以下信息,然后按 Enter 键:
      wmic recoveros set MiniDumpDirectory = 3

    解决蓝屏故障

      选择小内存转储, 选好后点“确定”,这样操作系统在下次出现蓝屏时,就会记录下当时内存中的数据,并存储为dump文件,该文件存放在系统盘的minidump文件夹下。
      附小知识:Dump文件
      Dump文件是用来给驱动程序编写人员调试驱动程序用的,这种文件必须用专用工具软件打开,比如使用WinDbg打开。
      第二步:从微软的网站下载安装WinDbg
      WinDbg是微软发布的一款优秀的源码级调试工具,可以调试Dump文件,这里我们用来查找蓝屏故障的原因。
      第三步:使用WinDbg诊断蓝屏错误
      系统再次出现蓝屏后重启,在minidump文件夹下会出现一个以日期为文件名的.dmp文件,这就是我们要分析的文件。接下来点击“开始菜单→程序→Debugging tools for windows(x86)-WinDbg”,打开WinDbg程序,点击程序窗口的“File→Open Crash Dump”,打开位于系统盘的minidump文件夹下的以日期为文件名的.dmp文件。
      打开后程序就开始自动分析文件了,分析完后,看最下面,找到“Probably caused by”这一行,其后面的文件就是引起蓝屏的罪魁祸首。
      第四步:解决蓝屏故障
      我们对导致蓝屏的这个文件名在网上搜索,基本就知道是什么文件了,一般网上也有相关的解决办法,看看要删除些什么插件、打什么补丁或者重装软件等等。例如本中文分析出的360antiarp.sys文件,在网上一查,发现它是360安全卫士的ARP 防火墙驱动程序。由于该文件与本机的某些驱动程序冲突会引起电脑蓝屏。把360安全卫士的ARP 防火墙卸载,蓝屏问题就解决了。
      编后:本文只能帮你找出导致蓝屏故障的元凶,具体的解决办法还得上网查找。导致故障的原因可能是.sys文件也有可能是.dll文件,如果故障是由查不到的.sys文件或者.dll文件引起的就要当心了,这些文件有可能是病毒,最好在安全模式下全盘杀毒试试看!
    展开全文
  • 建立内存文件系统 在内存中建立一个虚拟磁盘; 建立文件系统; 设计合理的数据结构,管理虚拟磁盘中已分配和未分配的盘块; 设计相应的目录结构,文件控制块等来... 实现磁盘转储功能,使文件可以从虚拟磁盘转入内存
  • 内存分析器变体 IBM Java监视和诊断工具-内存分析器通过使用IBM Java诊断工具... DTFJ使用操作系统级转储和IBM可移植堆转储来启用Java堆分析。 IBM变体是IBM Support Assistant(ISA)的一部分。 DTFJ插件可用于...

    gdb调试转储文件

    一种常见的解决问题的方法是在代码中添加调试语句以写出对象中的字段,甚至写出整个数据集。 当您发现需要越来越多的信息来理解和解决问题时,通常必须迭代执行此操作。 尽管此过程可能有效,但有时可能无法取得成果:调试代码量可能导致问题消失,您可能需要将调试添加到您不拥有的代码中,调试可能需要您重新启动过程,或者调试对整体性能的影响可能会阻止应用程序运行。

    内存分析器是一个跨平台的开放源代码工具,您不仅可以使用它来诊断内存问题,还可以深入了解整个Java应用程序的状态和行为。 通过在应用程序运行时读取Java运行时创建的快照转储,Memory Analyzer提供了一种诊断调试代码可能无法公开的棘手问题的方法。

    本文介绍了如何生成转储并将其用于检查和诊断应用程序的状态。 使用Memory Analyzer,您可以检查线程,对象,包和整个数据集合,以调试Java代码问题,这些问题不仅限于内存泄漏。

    快照转储类型

    内存分析器当前可以使用三种转储类型:

    • IBM便携式堆转储(PHD):这种专有的IBM格式仅包含流程中每个Java对象的类型和大小以及对象之间的关系。 此转储文件格式明显小于其他格式,并且包含的​​信息最少。 但是,数据通常足以诊断内存泄漏并获得对应用程序体系结构和占用空间的基本了解。
    • HPROF二进制转储: HPROF二进制格式包含IBM PHD格式中存在的所有数据以及Java对象中保存的原始数据以及线程详细信息。 您可以查看对象内部字段中保存的值,并查看进行转储时正在执行哪些方法。 额外的原始数据使HPROF转储明显大于PHD格式的转储。 它们的大小与使用的Java堆大小大致相同。
    • IBM系统转储:使用IBM Java运行时时,可以将本机操作系统转储文件(AIX®或Linux上的核心文件,Windows®上的小型转储或z /OS®上的SVC转储)加载到内存分析器。 这些转储包含正在运行的应用程序的整个内存映像-HPROF格式的所有信息和数据,以及所有本机内存和线程信息。 这是最大,最全面的转储文件格式。

    两种IBM转储类型仅在安装了Java诊断工具框架(DTFJ)插件时才可用(请参阅参考资料Memory Analyzer变体侧栏)。

    表1总结了转储文件类型之间的区别:

    表1.转储类型的特征摘要
    转储格式 磁盘上的大概大小 对象,类和类加载器 线程详细信息 栏位名称 字段和数组引用 原始字段 基本数组内容 准确的垃圾收集根源 本机内存和线程
    IBM PHD Java堆大小的20% ÿ 使用Javacore * ñ ÿ ñ ñ ñ ñ
    HPROF Java堆大小 ÿ ÿ ÿ ÿ ÿ ÿ ÿ ñ
    IBM系统转储 Java堆大小+ 30% ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ

    *通过加载同时生成的javacore.txt文件(IBM线程转储文件)和heapdump.phd文件,Memory Analyzer可以在IBM PHD格式转储中提供线程详细信息。

    HPROF和IBM系统转储格式都可以使用操作系统工具很好地压缩,通常压缩到其原始大小的20%左右。

    获取快照转储

    可使用不同的机制来获取每个Java运行时的各种转储,从而提供了灵活性,可以让您为涉及OutOfMemoryError之外的场景生成快照转储。 可用的机制取决于您使用的供应商的Java运行时。

    先决条件

    对于所有转储类型,必须确保有足够的磁盘空间用于转储,以便不会被截断。 转储的默认位置是JVM进程的当前工作目录。 对于IBM JVM,可以使用-Xdump文件命令行选项更改此设置。 对于HotSpot JVM,可以使用-XX:HeapDumpPath命令行选项对其进行更改。 请参阅相关信息的链接,相关的语法。

    来自操作系统的转储可用于IBM和HotSpot JVM。 对于IBM JVM,可以使用jextract工具(与JDK一起提供)创建转储,然后将其直接加载到Memory Analyzer中。 对于HotSpot JVM,您可以使用jmap工具从核心转储中提取堆转储。 (我们将在本文后面详细讨论这两种技术。)但是,在某些操作系统上,必须确保在创建核心转储之前,该进程以足够的ulimit运行。 否则,核心转储将被截断并且分析将受到限制。 如果ulimit不正确,则必须对其进行修改并在收集转储之前重新启动该过程。 请参阅相关信息的链接,详细信息获取从AIX,Linux®的,Z / OS和Solaris系统转储。

    获取快照转储:HotSpot运行时

    基于HotSpot的Java运行时仅生成HPROF格式转储。 您可以选择几种交互式方法和一种基于事件的方法来生成转储:

    • 互动方式:
      • 使用Ctrl + Break :如果为正在运行的应用程序设置了-XX:+HeapDumpOnCtrlBreak命令行选项,则在Ctrl + Break事件或SIGQUIT (通常使用SIGQUIT生成)时会生成HPROF格式转储以及线程转储kill -3 ),通过控制台发送。 在某些版本上,此选项可能不可用,在这种情况下,请尝试:

        -Xrunhprof:format=b,file=heapdump.hprof
      • 使用jmap工具jmap实用工具(请参阅相关信息 ),在JDK的bin目录下交付,提供了一个选项,从正在运行的进程请求HPROF转储。 对于Java 5,请使用:

        jmap -dump:format=b pid

        在Java 6中,使用此版本,其中live是可选的,并且仅将“ live”对象写入转储文件进程ID(PID):

        jmap -dump[live,]format=b,file=filename pid
      • 使用操作系统 :使用nondestructive gcore命令或破坏性的kill -6kill -11命令来生成核心文件。 然后,使用jmap从核心文件中提取堆转储:

        jmap -dump:format=b,file=heap.hprof path to java executable core
      • 使用JConsole的工具:一个dumpHeap下提供操作HotSpotDiagnostic的MBean在JConsole中。 此操作要求生成HPROF转储。
    • 基于事件的方法:
      • OutOfMemoryError如果为正在运行的应用程序设置了-XX:+HeapDumpOnOutOfMemoryError命令行选项,则在发生OutOfMemoryError时会生成HPROF格式转储。 对于生产系统而言,理想的做法是将它安装到位,因为几乎总是需要使用它来诊断内存问题,并且不会产生持续的性能开销。 在基于HotSpot的Java运行时的较早版本中,对每个JVM运行此事件产生多少堆转储没有限制。 在较新的版本中,每个JVM运行在此事件上最多生成一个堆转储。

    获取快照转储:IBM运行时

    IBM运行时提供了转储和跟踪引擎,它们可以在大量基于交互和基于事件的场景中生成PHD格式或系统转储。 您也可以使用Health Center工具或以编程方式使用Java API生成交互式转储。

    • 互动方式
      • 使用SIGQUIT或Ctrl + Break:将Ctrl + Break或SIGQUIT (通常使用kill -3生成)发送到IBM运行时时,将在IBM转储引擎中生成用户事件。 默认情况下,此事件仅生成线程转储文件(javacore.txt)。 您可以使用-Xdump:heap:events=user选项生成PHD格式的转储,或使用-Xdump:system:events=user选项生成Java应用程序的系统转储。

      • 使用操作系统产生系统转储:

        • AIX: gencore (或破坏性kill -6kill -11
        • Linux / Solaris: gcore (或破坏性的kill -6kill -11
        • Windows: userdump.exe
        • z / OS: SVCDUMP或控制台转储
      • 使用IBM Java监视和诊断工具-Health Center: Health Center工具提供了一个菜单选项,用于从正在运行的Java进程中请求PHD或系统转储(请参阅参考资料 )。

    • 基于事件的方法。 IBM转储和跟踪引擎提供了一组灵活的功能,用于根据从抛出异常到执行方法的大量事件生成PHD和系统转储。 使用它们,您应该能够为要诊断的大多数问题方案生成转储:
      • 使用IBM转储引擎:转储引擎提供了大量事件,您可以在这些事件上产生PHD或系统转储。 此外,它还允许您过滤那些事件的类型,以便对何时生成转储进行更细粒度的控制。

        您可以使用-Xdump:what选项查看默认事件。 例如,您会注意到,JVM中的前四个OutOfMemoryError异常产生了heapdump.phd和javacore.txt。

        要收集更多数据,可以在OutOfMemoryError异常上生成系统转储而不是堆转储:

        -Xdump:heap:none -Xdump:java+system:events=systhrow,
         filter=java/lang/OutOfMemoryError,range=1..4,request=exclusive+compact+prepwalk

        一些异常,例如NullPointerException ,在大多数应用程序中通常是由大量代码生成的。 这使得很难在感兴趣的特定NullPointerException上生成转储。 为了帮助您更具体地了解将在哪个异常上生成转储,为“ throw”和“ catch”事件提供了额外的过滤级别,使您可以分别指定throwing和catching方法。 为此,您可以添加#分隔符,然后根据需要添加throwing或catch方法。 例如,当bad()方法抛出NullPointerException时,此选项会产生系统转储:

        -Xdump:system:events=throw,
               filter=java/lang/NullPointerException#com/ibm/example/Example.bad

        catch()方法捕获到NullPointerException时,此选项将产生系统转储:

        -Xdump:system:events=catch,
               filter=java/lang/NullPointerException#com/ibm/example/Example.catch

        除了对事件进行过滤之外,您还可以指定要在其上生成转储的一系列事件。 例如,此选项仅在第五次出现NullPointerException产生转储:

        -Xdump:system:events=throw, filter=java/lang/NullPointerException,range=5

        此选项使用范围仅在第二,第三和第四次出现NullPointerException产生转储:

        -Xdump:system:events=throw, filter=java/lang/NullPointerException,range=2..4

        表2总结了最有用的事件和过滤器:


        表2.可用的转储事件
        事件 描述 可用过滤
        gpf 一般保护故障(崩溃) -Xdump:system:events=gpf
        user 用户生成的信号( SIGQUIT或Ctrl + Break) -Xdump:system:events=user
        vmstop 虚拟机关闭,包括对System.exit()调用 退出码 -Xdump:system:events=vmstop,filter=#0..#10
        在VM关闭时生成系统转储,退出代码在010之间。
        load 类负荷 班级名称 -Xdump:system:events=load,filter=com/ibm/example/Example
        加载com.ibm.example.Example类时,生成系统转储。
        unload 类卸载 班级名称 -Xdump:system:events=unload,filter=com/ibm/example/Example
        卸载com.ibm.example.Example类时,生成系统转储。
        throw 引发异常 异常类名称 -Xdump:system:events=throw,filter=java/net/ConnectException
        生成ConnectException时生成系统转储。
        catch 被捕获的异常 异常类名称 -Xdump:system:events=catch,filter=java/net/ConnectException
        捕获ConnectException时生成系统转储。
        systhrow JVM将抛出Java异常。 (这与throw事件不同,因为它仅针对JVM内部检测到的错误情况才触发。) 异常类名称 -Xdump:system:events=systhrow,filter=java/lang/OutOfMemoryError
        生成OutOfMemoryError时生成系统转储。
        allocation 分配了Java对象 分配对象的大小 -Xdump:system:events=allocate,filter=#5m
        分配大于5MB的对象时,生成系统转储。
      • 使用IBM跟踪引擎:跟踪引擎允许在应用程序中运行的任何Java方法的方法入口或出口处触发PHD和系统转储。 通过对控制IBM跟踪引擎的-Xtrace命令行选项使用trigger关键字,可以完成此任务。 触发器选项的语法为:
        method{methods[,entryAction[,exitAction[,delayCount[,matchcount]]]]}

        在调用Example.trigger()方法时,向应用程序添加以下命令行选项会产生系统转储:

        -Xtrace:maximal=mt,trigger=method{com/ibm/example/Example.trigger,sysdump}

        调用Example.trigger()方法时,此命令行选项将生成PHD转储:

        -Xtrace:maximal=mt,trigger=method{com/ibm/example/Example.trigger,heapdump}

        但是,建议您设置一个范围,以免在每次调用该方法时都不创建转储。 本示例忽略对Example.trigger()的前五个调用,然后触发一个转储:

        -Xtrace:maximal=mt,trigger=method{com/ibm/example/Example.trigger,sysdump,,5,1}

        请注意,在此示例中, exitAction使用空术语,因为我们仅在方法条目上触发转储。
    • 编程方法: IBM运行时还提供了带有javaDump( ), heapDump()systemDump()方法的com.ibm.jvm.Dump类。 它们分别生成线程转储,PHD转储和系统转储。

    使用内存分析器获取转储

    除了运行时自身提供的获取转储的方法外,Memory Analyzer还提供了一个Acquire Heap Dump选项,如图1所示,它使您能够从运行在同一台计算机上的Java进程中触发并加载快照转储。作为内存分析器:

    图1.在内存分析器中使用“获取堆转储”功能
    该屏幕截图显示了内存分析器中的“获取堆转储”功能

    在基于HotSpot的运行时,内存分析器使用jmap生成转储。 对于IBM运行时,转储使用Java“后期附加”功能和编程API生成。 该功能需要Java 6 SR6,因为早期版本不包含“后期附加”功能。

    后处理要求

    对于IBM系统转储,必须使用JDK随附的jextract工具对转储进行后处理:

    jextract core

    理想情况下, jextract在产生转储的同一台物理计算机上运行,​​使用产生转储的同一JDK安装中的jextract ,并具有与运行java进程的相同库的读访问权限。 鉴于jextract会消耗大量CPU周期来处理转储,因此在某些生产系统中这可能是不可接受的。 在这种情况下,应该在最接近的匹配系统(例如生产前测试系统)上处理转储。 Java运行时的服务刷新(SR)和修订包(FP)版本应匹配。

    jextract生成一个ZIP文件,该文件包含原始核心转储,转储的经过处理的表示形式,Java可执行文件以及java进程使用的库。 您可以在运行jextract后删除原始(未压缩)核心转储。 ZIP文件是您应该加载到Memory Analyzer中的文件。

    您可以提取从一个PHD转储jextract通过装载ZIP进入编辑系统转储jdmpview和执行heapdump命令(请参阅相关的主题 )。

    使用内存分析器分析问题

    内存分析器可以通过查找应用程序的某些区域来诊断OutOfMemoryError ,这些区域要么泄漏内存,要么对可用内存的占用空间太大。 内存分析器会自动进行泄漏检测并生成“泄漏可疑”报告(请参阅参考资料 )。

    HPROF和IBM系统转储中可用的其他数据,尤其是字段名称和字段值-以及Inspector视图和对象查询语言(OQL)的功能-还可以诊断比以下类型更广泛的问题类型“什么在使用所有内存?”。 例如,您可以确定集合的占用率和负载因数,以查看它们的大小是否有效,或者查看与ConnectException关联的主机名和端口,以查看应用程序试图创建的连接。

    使用检查器查看对象中的字段

    在“内存分析器”中选择任何对象时,“检查​​器”视图将显示与该对象有关的可用信息,包括类层次结构,属性和静态信息。 “属性”面板显示与对象关联的实例字段和值,而“静态”面板显示与类关联的静态字段和值。

    图2所示的Inspector视图提供了一个简单的java.net.URL对象,您可以查看有关该对象的详细信息,包括URL所适用的协议类型和目标:

    图2. Inspector视图中的Statics,Attributes和Class Hierarchy面板
    屏幕快照显示了“检查器”视图中的三个面板

    图2中 ,您可以在“属性”面板中看到URL对象引用位于本地文件系统上(由path和file字段指定的位置)的JAR文件(协议字段)。

    使用OQL对对象运行查询

    OQL可用于使用类似于SQL的自定义查询来查询转储。 该主题本身可能只是一篇文章,因此我们仅重点介绍一些示例。 有关更多详细信息,请查阅Memory Analyzer中提供的OQL帮助内容。

    OQL对于遵循从一组对象的传出引用和字段到特定字段的路径特别有用。 例如,如果类A的字段fooB类型,而类B的字段barString ,则查找所有这些String的简单查询将是:

    SELECT aliasA.foo.bar.toString()
    FROM A aliasA

    我们给类A别名aliasA ,然后在SELECT子句中引用它。 此查询严格仅从类A实例中选择。 如果要从类A所有实例以及任何子类中进行选择,则可以使用:

    SELECT aliasA.foo.bar.toString()
    FROM INSTANCEOF A aliasA

    这是DirectByteBuffer的更复杂的示例:

    SELECT k, k.capacity
    FROM java.nio.DirectByteBuffer k
    WHERE ((k.viewedBuffer=null)and(inbounds(k).length>1))

    在这种情况下,我们想要获取任何DirectByteBuffer的容量字段,该字段给出该对象持有的本机内存。 我们还希望过滤掉任何DirectByteBuffer S作空viewedBuffer场(因为这些都只是为其他视图DirectByteBuffer S)和一个以上的入站引用(所以我们不看那些未决DO清理他们的虚引用—也就是说,我们只需要“实时” DirectByteBuffer )。

    在视图或转储之间进行比较

    使用内存分析器,您可以比较查询生成的表。 这些表可以来自同一转储,让您查看一个视图中的String对象是否存在于另一视图中看到的集合对象中,也可以跨不同的转储,让您查找数据的变化,例如对象集合的增长。

    要进行比较,请将相关表添加到“比较篮”,然后请求比较篮中的条目。 首先,在Navigation History中找到并选择表的条目,然后从上下文菜单中选择Add to Compare Basket ,如图3所示:

    图3.将表从Navigation History视图添加到Compare Basket
    屏幕截图显示了内存分析器中的“添加到比较篮”功能

    在“比较购物篮”中有两个条目之后,可以使用面板右上角的“比较结果”按钮(红色感叹号)运行比较,如图4所示:

    图4.比较比较篮中条目的结果
    屏幕截图显示了内存分析器中的“比较结果”功能

    占用空间和存储效率

    内存分析器的另一个重要用途是查找哪些组件正在使用大部分堆,即使在没有内存泄漏的情况下也是如此。 如果可以减少内存使用量,则可以提高系统的容量或性能,从而允许更多的会话或更少的垃圾收集时间。

    顶级组件报告是第一步。 它按系统中的组件划分内存使用情况,分析每个组件中的使用情况,并寻找浪费的做法。 可以说,由另一个对象控制(保留)另一个对象的对象由该控制者拥有 。 “顶部组件”报告列出了不属于另一个对象的所有对象。 这些是堆的主要控制者。 然后,使用对象的类由类加载器将顶级控制者划分开,并将所有这些顶级控制者和它们所拥有的对象分配给适当的类加载器。 您可以通过在报告中选择一个类加载器来打开一个新的特定于类加载器的组件报告来进一步分析。

    对于每个组件,都会分析Collections对象。 java.util.*所示,Collections类为程序员节省了很多时间,它提供了经过测试的列表,集合和映射的实现。 一般的应用程序可以包含数百万个集合,因此集合中的浪费空间可能非常大。

    空集合是浪费内存的常见原因之一。 ArrayListVectorHashMapHashSet的创建具有默认大小的后备数组,该数组可能包含10个条目,可以随时保存条目。 在应用程序中创建集合但没有存储对象的情况令人惊讶地常见。 这会Swift消耗内存。 例如,对于100,000个空集合,仅支持数组就可以消耗100,000 *(24 + 10 * 4)字节= 6MB。

    空集合报告查看标准集合类及其扩展,并按集合大小分析它们。 然后,它为每个集合生成一个表,该表按集合的大小排序,最频繁的大小在前。 如果集合类型的大部分实例为空,则该报告会将其标记为可能的内存浪费。

    一种解决方案是延迟分配集合,直到需要插入一个条目为止。 另一个方法是分配一个默认大小为0或1的集合,如果需要,可以使其增长,但需要一些运行时成本。 第三是在初始化阶段完成后将集合调整为适当大小。

    一个相关的领域是只有几个条目和大量浪费空间的集合。 “集合填充率”部分针对每种集合类型显示具有特定填充率的该集合的实例数。 这显示出具有很大空白空间的集合。

    字符串重复

    字符串和字符数组在典型的业务应用程序中占用大量空间,因此它们是另一个值得分析的领域。 组件报告的此部分分析常见内容的字符串。 字符串是不可变的。 VM规范保证具有相同值的字符串常量使用相同的实例。 动态构建的字符串没有这种保证,例如,通过从数据库或磁盘中读取具有相同值的数据而构建的两个String ,将具有单独的实例和单独的后备字符数组。 如果保留这些字符串,那么这可能很重要。

    您可以通过使用String.intern()或维护用户哈希集或哈希映射来解决此问题。

    浪费的char数组

    通过建立共享原始字符数组的新String ,以Java语言实现String.substring( )。 如果仍然需要原始字符串,这将非常有效。 如果只需要一个小的子字符串,那么-因为保留了整个字符数组-浪费了一些空间。 “在字符数组中浪费”查询显示仅由字符串引用的字符数组中浪费的空间量。

    Eclipse捆绑包和类加载器层次结构

    现代应用程序通常基于类加载器分为多个组件,以在应用程序的各个部分之间提供一定程度的隔离。 可以通过停止使用一个组件类加载器并使用新的类加载器加载组件的新版本来更新组件。 随着时间的推移,假定应用程序不包含对类或对象或类加载器的外部引用,则可以通过垃圾回收释放旧版本。

    Class Loader Explorer查询显示了系统中的所有类加载器,因此适用于所有应用程序。 它显示了由类加载器加载的类以及类加载器的父链,以便可以理解类加载问题。 通过检查,您可以查看是否存在一个类加载器的多个副本。 如果类加载器几乎没有定义类的实例,则该类加载器很可能是空闲的。

    重复类查询显示了由多个类加载器加载的类名称。 这可能表明类加载器内存泄漏。 它仅需引用系统中其他位置(例如注册表)中保存的对象,即可发生类加载器泄漏。 该对象保留对其类的引用,对类加载器的引用,对所有已定义类的引用。

    常见的类加载框架是OSGi框架。 一种实现是Eclipse Equinox,用于基于Eclipse的应用程序以分隔插件,并且还用于WebSphere®Application Server 6.1和更高版本。 尝试了解应用程序的状态时,了解所有捆绑软件的状态很有用。 如图5所示,Eclipse Equinox Bundle Explorer查询就是这样做的:

    图5. Eclipse Bundle Explorer
    屏幕快照显示了Bundle Explorer视图

    系统或HPROF转储具有所有对象和字段。 捆绑包浏览器显示系统中的所有捆绑包,以及它们的状态和依赖关系,依赖关系和服务。 它可以显示异常活跃的捆绑包,因此会使用更多资源。

    线程数据使用

    表1所示 ,转储可以包括线程详细信息,这些线程详细信息可以提供对转储时正在发生的事情的独特见解。 这可以包括所有活动线程堆栈,每个线程的所有框架,最重要的是,这些框架上的部分或全部活动Java局部语言。

    线程概述视图

    如图6所示,“线程概述”视图显示了JVM中的每个线程以及该线程的各种属性,例如其保留的堆大小,上下文类加载器,优先级,状态和本机ID:

    图6.线程概述
    该屏幕快照显示了“线程概述”视图

    保留堆大小在OutOfMemoryError期间本身没有发生Java堆问题的情况下特别有用,而线程保留堆的总和“太多”。 在这种情况下,JVM的大小可能不足,线程池的大小可能太大,或者线程的平均或最大Java堆“负载”太大。

    线程堆栈视图

    如图7所示,“线程堆栈”视图显示了每个线程,其堆栈,堆栈框架以及这些堆栈框架上的Java本地语言:

    图7.线程堆栈视图
    该屏幕快照显示了“线程堆栈”视图

    图7的示例中,扩展了一个类型为java.lang.Thread且名称为main (简单命令行程序中的主线程)的线程。 将显示该线程的每个堆栈框架,并且具有可用Java本地语言的那些框架都是可扩展的。 在这种情况下,已将String作为参数从Play.method1Play.method2 ,并且字符串user1的内容以红色圆圈突出显示。 您可以想象基于每个线程堆栈帧中发生的事件以及基于哪些对象,能够对转储时发生的事件进行重构或逆向工程的能力。

    请注意,由于运行时优化,并非所有相关对象(例如方法参数或对象实例)都将可用(尽管这些对象将在转储中),但通常会“主动处理”那些对象。

    异常分析

    当应用程序中生成异常时,其他复杂情况会使分析异常原因更加困难。 这种困境的两个例子是:

    • 使用日志记录机制意味着异常丢失或异常消息被删除。
    • 异常是生成一条包含足够信息的消息。

    在第一种情况下,异常消息或整个异常都将完全丢失,从而很难知道问题是否存在或难以获得有关该问题的基本信息。 在第二种情况下,已记录了异常,并且异常消息和堆栈跟踪可用,但是它不包含解决异常原因的必要信息。

    由于Memory Analyzer可以访问对象内部的字段,因此可以从异常对象中找到异常消息。 在某些情况下,还可以提取原始异常中没有的其他数据。

    在快照转储中查找异常

    定位快照转储中存在的异常的一种方法是使用内存分析器中的OQL功能来定位转储中的目标对象。 例如,此查询查找所有异常对象:

    SELECT * 
    FROM INSTANCEOF java.lang.Exception exceptions

    下一个查询产生所有异常的列表,您可以使用Inspector视图查看每个异常内的字段。 知道包含异常消息的字段是detailMessage字段,您还可以修改查询以直接提取异常消息并将它们立即显示为结果表的一部分:

    SELECT exceptions.@displayName, exceptions.detailMessage.toString() 
    FROM INSTANCEOF java.lang.Exception exceptions

    前面的查询产生图8所示的输出:

    图8. OQL查询的异常输出,包括异常消息
    屏幕快照显示了OQL查询的输出

    图8显示了应用程序中仍然存在的每个异常,以及抛出该异常时将显示的消息。

    提取与异常有关的其他信息

    尽管从转储中找到异常对象可以使您恢复异常消息,但有时异常消息过于笼统或含糊,无法使您理解问题的原因。 一个很好的例子是java.net.ConnectException 尝试建立与不接受连接的主机的套接字连接时,会出现以下消息:

    java.net.ConnectException: Connection refused: connect
         at java.net.PlainSocketImpl.socketConnect(Native Method)
         at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:352)
         at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:214)
         at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:201)
         at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:377)
    
         at java.net.Socket.connect(Socket.java:530)
         at java.net.Socket.connect(Socket.java:480)
         at java.net.Socket.(Socket.java:377)
         at java.net.Socket.(Socket.java:220)

    如果您有权访问创建套接字的代码,并且可以从代码中看到正在使用的主机名和端口,则此消息就足够了。 如果是更复杂的代码,其中主机名和端口值是由于它们是从外部来源(用户输入值,数据库等)获得的,因此可能会发生更改,因此该消息无法帮助您理解为什么连接被拒绝了。

    堆栈跟踪应包括一个包含有用数据的套接字对象,如果可以使用Memory Analyzer在快照转储中找到该套接字对象,则可以找出哪个主机名和端口拒绝了该连接。

    最简单的方法是在引发异常时生成转储。 可以使用以下-Xdump选项集在IBM运行时上完成此操作:

    -Xdump:system:events=throw,range=1..1,
           filter=java/net/ConnectException#java/net/PlainSocketImpl.socketConnect

    此选项在由PlainSocketImpl.socketConnect()方法生成的第一次出现ConnectException生成IBM系统转储。

    将生成的快照转储加载到Memory Analyzer之后,我们可以使用Open Query Browser> Java Basics> Thread Stacks选项在线程的堆栈跟踪中列出线程和与每个方法关联的对象。

    By expanding the current thread and the method frames in the thread, you can look at the objects associated with those methods. In the case of a java.net.ConnectException , the most interesting method is java.net.Socket.connect() . Expanding this method frame shows a reference to a java.net.Socket object in memory. This is the socket connection we were trying to make.

    When the Socket object is selected, the fields are shown in the Inspector view, as you can see in Figure 9:

    Figure 9. Inspector view for the Socket object
    Screen shot showing the Inspector view for a Socket object

    The information in Figure 9 isn't too useful, because the real implementation of the Socket is in the impl field. You can inspect the contents of the impl object by either expanding the Socket object and selecting the impl java.net.SocksSocketImpl line in the main panel, or by right-clicking on the impl field in the Inspector view and selecting Go Into . Now the fields for SocksSocketImpl are visible in the Inspector view, as shown in Figure 10:

    Figure 10. Inspector view for the SocksSocketImpl object
    Screen shot showing the Inspector view for a Socket Impl object

    The view shown in Figure 10 gives access to the address and port fields. In this case, the port is 100 , but the address field points to a java.net.Inet4Address object. Following the same process to look into the fields of the Inet4Address objects shows the results displayed in Figure 11:

    Figure 11. Inspector view for the Inet4Address object
    Screen shot showing the Inspector view for a Inet4Address object

    You can see that the hostName is set to baileyt60p .

    技巧和窍门

    Here are a few tips and tricks that may be useful:

    • Don't forget that Memory Analyzer itself may run out of memory. For the Eclipse MAT, edit -Xmx in the MemoryAnalyzer.ini file. For the ISA version, edit the ISA Install /rcp/eclipse/plugins/com.ibm.rcp.j2se.../jvm.properties file.
    • If you're still running out of memory on a 32-bit version of Memory Analyzer, use the 64-bit version of Eclipse MAT or try the headless mode (see Related topics ). (The ISA tool currently does not currently support 64-bit.)
    • Memory Analyzer writes "swap" files in the directory of the dump, which lessens the dump's reload time. These files can be zipped, sent to another machine, and placed in the same directory as the dump, making a complete reload of the dump unnecessary.
    • If a dump's size does not correlate with the garbage collector at the time of the dump, consult the Unreachable Objects Histogram link in the Overview tab. The Java heap may have had a lot of garbage (for example, if a tenured collection hadn't run for some time) that Memory Analyzer removed.
    • If two objects A and B do not have direct references to each other, but both have outgoing references to some set of objects C , then the Retained Heap of the set C will not be included in either of the retained sets of A or B , but rather in the retained set of the dominator of both A and B . In some situations, B may be temporarily observing the set C , which is actually the progeny of A . In this case, you can right-click on A and select Java Basics > Customized Retained Set and use the address of B as the exclude ( -x ) parameter.
    • You can load multiple dumps at once and compare them. Open the Histogram of the more recent dump, click the Compare button at the top, and choose the baseline dump.
    • When you are exploring a reference tree, be aware that references can refer, directly or indirectly, back to a "parent" reference, so that you could enter an exploration loop or cycle (for example, in a linked list). Be aware of the object addresses. Also, be aware that if the class name of an object is preceded by the word class , that you are exploring the static instance of that class.
    • The String value displayed in most views is limited to 1,024 characters. If you need the whole String , right-click on the object and select Copy > Save value to file .
    • Most views have an export option, and most HTML results are created on the file system, so that data can be exported for sharing or further transformation. Relatedly, you can press Ctrl+C on any selection of rows in a grid to copy a textual representation of those rows to your clipboard.

    Memory Analyzer was originally developed as "a fast and feature-rich Java heap analyzer that helps you find memory leaks and reduce memory consumption," as it's described on Eclipse.org. But its capabilities clearly stretch far beyond that description. In addition to their role in diagnosing "normal" memory problems, snapshot dumps can be used as an alternative to, or in addition to, other types of problem-determination techniques such as tracing and patching. Particularly with HPROF dumps and IBM system dumps, Memory Analyzer gives you memory contents such as primitives and the field names from the original source code. Using the various views covered in this article, you can explore or reverse-engineer the problem at hand, including overall footprint and memory efficiency, Eclipse bundles and classloader relationships, thread data usage and stack frame locals, exceptions, and more. OQL and the Memory Analyzer plug-in model also allow you to inspect the dump more easily using a query language and programmatic methods that can help in automating common analysis.


    翻译自: https://www.ibm.com/developerworks/opensource/library/j-memoryanalyzer/index.html

    gdb调试转储文件

    展开全文
  • 本文描述如何利用内存转储来定位嵌入式板子上应用程序Crash,当前开发环境为BCM 6828。   一、 开启内核支持,当前BCM 6828默认没有开启。 1、如果之前编译过,先删除kernel/linux/vmlinux,否则编译流程不走第二步...

    本文描述如何利用内存转储来定位嵌入式板子上应用程序Crash,当前开发环境为BCM 6828

    一、 开启内核支持,当前BCM 6828默认没有开启。

    1、如果之前编译过,先删除kernel/linux/vmlinux,否则编译流程不走第二步。

    2、编辑hostTools/scripts/defconfig-bcm.template文件,找到CONFIG_ELF_CORE这项,改为

    CONFIG_ELF_CORE=y,当前BCM的内核选项配置文件是使用hostTools/scripts/gendefconfig生成,最终会使用defconfig-bcm.template覆盖内核目录的.config

    3、编译内核,并下载到当前调试的板子上。(注意,这里有时候编译出的镜像会加载DSP驱动模块失败,重新全编译一下,再下载到板子上就可以了,原因不知)

    重新编译内核时会提示生成的内存转储文件是否包含ELF头信息,当前FLASH空间够用,选上它。

    二、修改应用程序代码,生成内存转储文件并去除编译优化选项。

    1、修改应用程序的Makefile编译文件,主要保证使用-g调试选项、并去除-o优化选项,来编译当前应用程序项目,如果不修改的话,后面进行GDB分析时,调试信息会显示不太全。

    2、修改应用程序的代码,去除应用程序中含有Linux信号处理的所有代码,否则无法生成内存转储,并在应用程序的启始代码处添加如下代码,下面代码主要开启内存转储(当前如果不添加如下代码,在板子上使用ulimit -c命令设置也可以,但主要考虑有些嵌入式项目中busybox没有开启该命令,或者有些嵌入式项目的应用程序是脚本拉起,脚本拉起的应用程序要正常使用ulimit命令必须在脚本里添加,所以这些都不如直接在代码中开启比较稳妥),添加如下代码后,会将内存转储生成到/var目录下(生成内存转储的目录一定要可写),生成的名件名为“vtp_core_当前信号_当前时间.当前进程ID”。

    #include <stdlib.h>
    #include <sys/resource.h>
    #include <errno.h>
     
    int vtpEnableCoreDump(int iFlag)
    {
        struct rlimit stRlim = {0};
    
        stRlim.rlim_cur = stRlim.rlim_max = iFlag ? RLIM_INFINITY : 0;
    
        if (0 != setrlimit(RLIMIT_CORE, &stRlim))
        {
            printf("Error: setrlimit failed, %s\n", strerror(errno));
            return 0; 
        }
        else
        {
            system("echo /var/vtp_core_%s_%t > /proc/sys/kernel/core_pattern");
            system("echo 1 > /proc/sys/kernel/core_uses_pid");
            system("echo 1 > /proc/sys/fs/suid_dumpable");
            printf("Set coredump file size to %lu, path = /var\n", stRlim.rlim_cur);
            return 1;
        }
    
        return 0;
    }
    
    vtpEnableCoreDump(1);
    
    

    如下图为作者本人项目上测试的代码,在当前项目的启始处屏蔽了系统信号处理相关代码,并添加了开启内存转储的代码。
     

    3、为了方便测试,我在本人项目的代码流程中故意加入了产生Crash的错误代码。

    三、将编译好的调试版本烧录到板子上,这里一定要记得之前编译选项加上-g,并去掉-o的优化选项。

    四、调试

    1、前面流程在应用程序代码中故意加入产生Crash的代码,进行操作使得应用程序触发我们故意添加的Crash,此时会在/var目录下生成如下内存转储文件。

    2、将板子产生的内存转储文件下载到本地的编译主机上。

    3、在本地编译主机使用交叉编译工具链中的GDB程序进行调试,GDB程序的第一个参数-c指示内存转储的文件位置,第二个参数是之前编译好的应用程序可执行文件。

    GDB里我们很明显看到,当前收到了11段错误信号,程序死在spucps.c文件,1280行,cps_tele_digit函数,*p = “123”的代码位置。

    还可以使用bt查看死得时候的函数调用,其它查看方法可以参考GDB手册。

    备注:

    并非所有信号都可以产生coredump文件,详细哪些信号可以产生coredump文件请参考《APUE》圣经里的介绍

    展开全文
  • 说说 JVM 的堆转储文件以及获取方式

    千次阅读 2019-08-17 16:32:54
    JVM 的堆转储文件(heap dump)是某个时间点、Java 进程的内存快照。包含了当时内存中还没有被 full GC 回收的对象和类信息。 1 文件内容 堆转储文件包含以下内容: 所有对象 - 对象所对应的类、字段、原生数据类型...

    JVM 的堆转储文件(heap dump)是某个时间点、Java 进程的内存快照。包含了当时内存中还没有被 full GC 回收的对象和类信息。

    1 文件内容

    堆转储文件包含以下内容:

    1. 所有对象 - 对象所对应的类、字段、原生数据类型以及引用。
    2. 所有类 - Classloader、类名、超类以及静态字段。
    3. 垃圾回收器的根 - Java 垃圾回收就是使用它,进行可达性分析,从而判定一个对象是否可以被回收。
    4. 线程堆栈与本地变量。

    因为堆转储文件没有保存共享信息,所以找不到对象创建者信息。

    2 自动生成模式

    我们可以在 JVM 中配置 -XX:+HeapDumpOnOutOfMemoryError,这样在发生内存溢出异常(OutOfMemoryError)时,就会在工作目录中,自动生成堆转储文件。

    3 手动生成模式

    3.1 jmap 命令

    jmap -dump:format=b,file=<filename.hprof> <pid>
    
    • 其中的 format=b,表示转储为二进制格式。
    • file 指定转储文件的路径,后缀为 hprof。
    • pid 表示进程 ID。

    在 windows cmd 中,可以使用命令 tasklist 来查看进程 ID。

    3.2 jconsole 控制台

    Jconsole (Java Monitoring and Management Console),是 JDK 自带的监控 、管理工具 。

    首先双击 ${JDK_HOME}/bin/jconsole.exe,打开进程连接列表,选择我们需要 dump 的进程:

    默认是使用 SSL,本地一般不会用到,所以这里直接选择 “不安全的连接”:

    连接成功后,就会进入监控概览:

    依次选择 MBean → com.sun.management 下 HostSpotDiagnosic 中的 dumpHeap,在 p0 中输入 hprof 文件的导出路径,这样就可以生成堆转储文件啦:

    3.3 Eclipse Memory Analyzer

    也可以使用 Eclipse Memory Analyzer,直接从进程中生成堆转储文件。打开 Memory Analyzer,点击右上角的 File → Acquire Heap Dump,这时就会打开本地进程列表,我们选择想要 dump 的进程,并指定好堆存储路径:

    点击 Next ,就会进入 Heap Dump Provider 参数配置页,在此我们可以配置导出的类型、是否只导出活跃对象、是否压缩以及制定导出路径参数:


    个人更喜欢 jmap 命令,简单、清晰。

    展开全文
  • 目录 问题如下: 解决: 总结: 问题如下: 脱壳的时候我下了硬件断点:在PUSHAD的下一步查看ESP,OD的左下角...但是内存转储出来的exe打开无效果不运行,在110版本的OD中提示:“hasentrypointoutsidethecode...
  • 在Node.js开发中,核心转储分析可以帮助调试程序崩溃和内存泄漏。 IBM SDK for Node.js通过IBM监视和诊断工具-交互式诊断数据资源管理器 (IDDE)为Node.js应用程序提供了一种新的核心转储分析和调试方法。 IDDE是...
  • 20.windbg-.dump(转储文件)

    千次阅读 2012-05-21 15:24:20
    .dump 命令创建一个用户模式或内核模式崩溃转储文件。 程序崩溃(crash)的时候, 为了以后能够调试分析问题, 可以使用WinDBG要把当时程序内存空间数据都保存下来,生成的文件称为dump 文件。 步骤: 1) 打开...
  • 1. 修改注册表 当程序崩溃时 产生崩溃转储文件(dmp) a) OpenDump.bat - 自动生成dmp文件 b) 注册表 参数说明: c) CloseDump.bat - 关闭此功能 2. 在程序中加入代码 3. 任务管理器 - 适用崩溃未立即退出 4. ...
  • 内存文件系统

    2013-07-05 10:20:58
    内存文件系统:建立基于内存文件系统。 首先在内存中建立虚拟磁盘; 在该磁盘上建立相应的文件系统; 为该文件系统设计相应的数据结构来管理目录、虚拟磁盘的空闲空间、已分配空间等。 提供文件的创建、删除、移位...
  • Oracle 跟踪文件文件转储(dump) 一、Oracle跟踪文件分类 Oracle跟踪文件分为三种类型,如下: 一种是后台报警日志文件,记录数据库在启动、关闭和运行期间后台进程的活动情况,如表空间创建、回滚段...
  • 1、gdb 可执行文件 进入gdb调试。 2、break + 行号/函数名 打断点。 3、info break 查看断点信息。 4、delte + 断点编号 删除断点。 5、run让程序从头开始运行,遇到断点停止。 6、continue让程序继续运行。当程序...
  • 建立基于内存文件系统

    热门讨论 2011-12-26 17:04:06
    内存文件系统:建立基于内存文件系统。 首先分配一定容量的内存,建立虚拟磁盘; 在该磁盘上建立相应的文件系统; 为该文件系统设计相应的数据结构来管理目录、虚拟磁盘的空闲空间、已分配空间等。 提供文件的创建...
  • 我将进行最后的清除,并删除多余的代码,然后我将进行最后的提交。 联系人: wiresharkGD@gmail.com || @Hexploitable ##指示 在反汇编程序中打开目标应用程序,获取要挂接的方法的前〜16个字节(您可以自定义...
  • 第9章操纵数据库数据宋钰课程目标• 通过本章的学习,应该完成以下学习目标:学会在SQL 中使用SELECT、INSERT、UPDATE和DELETE语句操纵数据学会使用数据转储导出数据学会使用数据转储导入数据学会使用SQL Loader加载...
  • 一、Oracle跟踪文件 Oracle跟踪文件分为三种类型,一种是后台报警日志文件,记录数据库在启动、关闭和运行期间后台进程的活动情况,如表空间创建、回滚段创建、某些alter命令、日志切换、错误消息等。在数据库出现...
  • Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 ...目录内存泄漏检测实践翻译:使用 Memory Profiler 查看 ...
  • 一、Oracle跟踪文件 Oracle跟踪文件分为三种类型: 一种是后台报警日志文件,记录数据库在启动、关闭和运行期间后台进程的活动情况,如表空间创建、回滚段创建、某些alter命令、日志切换、错误消息等。在数据库...
  • 一、Oracle跟踪文件Oracle跟踪文件分为三种类型:一种是后台报警日志文件,记录数据库在启动、关闭和运行期间后台进程的活动情况,如表空间创建、回滚段创建、某些alter命令、日志切换、错误消息等。在数据库出现故障...
  • 一个文件映射可以有多个映射区域,以便用户可以文件的各个部分与进程的地址空间关联起来,而不必将整个文件映射到地址空间中,因为文件可以大于整个地址空间过程(通常的32位系统中的9GB DVD映像文件)。...
  • 提供文件的创建、删除、移位、改名等功能。 提供良好的界面,可以显示磁盘文件的状态和空间的使用情况; 提供虚拟磁盘转储功能,可将信息存入磁盘,还可从磁盘读入内存; 完全实现了上面的功能,验收的时候老师给了...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 19,817
精华内容 7,926
关键字:

内存转储文件可以删除