调优的并不总是速度,有时候需要调整应用程序的其他方面,如果应用程序需要调优,要做的第一件事通常是使用剖析程序监控应用程序。但是,剖析并不总是可行的,有时候原因可能很可笑。 关注性能的本期文章中, Jack 和 Kirk 讲述了他们最近经历的一件事:他们奉命剖析一个胖客户机,事实上它是如此庞大,根本没有为剖析程序留下空间。
我们从来还没有遇到过调优应用程序内存占用的问题。通常,我们看到的和内存有关的调优要求都涉及到降低垃圾收集的开销,理想情况下可以通过调整堆的大小或者改变垃圾收集算法来解决,如果不行的话,还可以采用各种技术减少内存中的对象。但是,有时候无论分配和垃圾收集的效率如何,应用程序都要占用很多的内存。
减肥中心之旅
最近,我们奉命降低一个胖客户机的内存占用。虽然“胖客户机”一词通常表示普通的 GUI 客户应用程序,而这个客户机却是几近肥胖症。这个客户机在 Windows 平台上运行,处理大小的极限是 2 GB。去掉可执行地址空间和引入各种 JNI 产品所需要的其他空间之后,该应用程序能够使用的最大堆大小大约是 1.2 GB 或者 1.3 GB。不幸的是,某些用户因为要向该应用程序灌输大量的数据,以至于占用的空间常常接近这个极限。最明显的调优方案是转移到 Unix 机器上,但是因为不切实际而被排除掉了——客户更愿意让这个应用程序减肥。
于是,我们的任务就定下来了。对这个胖客户机进行剖析,看看到底是什么占用了这些空间。然后对这些对象减肥,为以后的扩展或者更大的数据量留下空间。我们认为这事很容易。可能要花点时间,因为减少对象的数量通常不能一蹴而就,但是这么大的堆, 肯定有很多赘肉能够割掉。我们这样想。
通常的过程
我们开始了通常的内存占用缩减过程:建立测试环境、规定可再现的测试、启动剖析程序、运行测试、分析数据、查找调优的机会。时间不断流逝,我们一直忙个不停……或者说我们是这样认为的。现在,我们进入了“运行测试”阶段,剖析程序趴下了。于是我们再次尝试。又死掉了。我们改变了剖析程序的配置,将开销减到最少,再次尝试。又死掉了。根本就没留下足够容纳剖析程序完全运行的 JVM 堆空间,更不用说生成任何有用的剖析数据了。而我们使用的是一种上等的商业剖析程序,一般是很可靠的,所以我们很吃惊。
试一次,再试一次
没关系,海里有数不清的鱼,现在也有数不清的剖析程序(关于剖析程序的最新评述,请参阅 Resources)。又是一天,又使用了一个剖析程序,怎么样呢?不幸的是,测试过程是惊人的相似。和一号剖析程序差不多在同一点上,二号剖析程序又让 JVM 崩溃了。和一号剖析程序一样,它甚至可以做更多的配置,重新配置,降低开销,去掉更多的数据。但它还是和一号剖析程序一样,也崩溃了。糟糕的是,三号剖析程序也没有什么不同。
巧妙的剖析程序
但是,四号剖析程序有了微妙的变化。对存活对象的快照进行内存分析(忽略对象的创建和垃圾收集,只观察某一点上存活对象的快照),在请求进行快照之前,四号剖析程序根本没有增加 JVM 的开销。成功了!我们的测试第一次在剖析程序运行的时候通过了需要拍摄快照的那个点。我们很高兴。然后我们激活了快照,于是 JVM 崩溃了。
我们又尝试了一次,但是这个剖析程序生成快照需要太多的额外空间。根本无法工作。我们又回到了起点!尽管还有半打商业剖析程序可供尝试,但结果是显然的。应该做一些横向思考了。
具有讽刺意味的是,我们的问题正在于剖析程序本身的复杂性。我们需要某种简单的东西。当然,简单并不意味着开销低,但是既然那些复杂的剖析程序令我们失望,不妨试一试。于是我们开始扫描开放源代码剖析程序。
重新开始
我们首先寻找那些看来是用于内存分析的剖析程序。一号开发源代码内存剖析程序看起来绝对简单,也许过于简单了。输出结果用处不大,只有一个类列表和每个类的对象个数。但无论如何这也算是一个不错的起点。它崩溃了。我们陷入了重走老路的担忧。二号开放源代码剖析程序甚至比一号还简单,虽然它实际上给出了更详细的信息:每个对象都有堆占转储记录,说明对象的大小和所属的类。和其他剖析程序一样,我们用较低的配置尝试,于是可以看到堆转储逐渐增大——大致就是堆的大小,然后,我们看到的是一个 1 GB 的输出文件。我们尝试了它,它击溃了虚拟机。但它确实让我们看到了部分堆转储。
在处理像这种很大的因素时,必须能够判断所需资源的数量级和要花费的时间。转存 1 GB 的文件可能要花很多时间。如果没有考虑到一个操作可能花费多长的时间,您可能错误地认为进程被挂起了,而实际上它仍然在运行,只是要花费转储 1 GB 格式化文本所需要的时间。这个开放源代码剖析程序正在工作,但是第一次测试时我们忽视了给它足够的时间。更遭的是,第一次还没有结束的时候,我们又迫使它进行第二次转储,结果造成了崩溃。所幸的是,我们认识到问题在我们自己而不是剖析程序,有了较多的认识之后,我们再次进行了尝试并取得了成功。
heapprofile 剖析程序
那么,到底哪个剖析程序成功了呢?它就是 Matthias Ernst 编写的“heapprofile”。它仅用了一页 C 代码,使用 Java Virtual Machine Profiler Interface (JVMPI) 把堆转存成最简单的格式。甚至还要自己编译,网站上(请参阅 Resources)没有提供预编译的可执行文件。这种简单性正是我们在这个问题里所需要的。没有任何开销。除了绝对必要的之外,没有使用堆或者 JNI 资源。程序运行的时候它什么也不做,当我需要堆转储的时候,它仅仅遍历一次堆,直接将每个对象的大小和类转存到一个文件,没有在内存中创建任何结构,正是这种结构让其他所有剖析程序击溃了 JVM。
当然,事情还没有完。现在我们需要分析结果数据,使用它确定应用程序所用的对象。幸运的是,输出格式很容易解析。一旦找到了造成问题的对象,我们还需要找到分配这些对象的地方。为了降低开销,我们采用重新编译这几个类的简单策略,在构造函数中放上栈跟踪程序,Jack 的著作(请参阅 Resources)中详细描述了这种技术。这种简单的技术需要在构造函数中创建(而不是抛出)异常。异常中包含分配地点的栈踪迹。然后可以将所有对象的这些栈列成表格。因为多数栈都是相同的,标识调用栈以及链接到每个栈的相关实例个数需要存储的数据并不很多(最多几千个字符串)。
简单而丑陋
这都是些简单的技术,但并没有很高的生产率。我们更愿意使用功能完备的剖析程序输出数据,尤其是因为它们提供的数据更便于分析。我们本来希望从堆的根开始,向下跟踪较大的节,直到发现大量引用堆的对象,但是我们没有选择这个方法。
和通常使用调优技术相比,这次使用的技术比较简陋。但最终我们发现了一些完全不需要的对象,使用一些类的不同实现可以完全消除它们;另一些必需的对象也可以苗条一点,或者压缩到一起,减少其空间需求。对象缩减通常都是如此,胖客户机减肥也没有一定之规。和人类一样,让 Java 应用程序节食也是很困难的事情。也和节食一样,去掉身上多余的脂肪往往比您所想的要花费更长时间。令人遗憾的是,虽然我们从这个胖客户机上刮掉了两百兆字节,但它仍然没有瘦到足以容纳“真正的”内存剖析程序的运行。
结束语
我们曾经在 Unix 讨论组看到这样一个问题 —— “Unix 大师们使用什么编辑文本?”,随后的讨论纷纷开始鼓吹 vi、Emacs 等。但毫无疑问,正确的答案应该是“Unix 大师使用任何能用的工具编辑文本。” Java 平台拥有一些非常杰出的剖析程序。但最终,调优应用程序必须分析数据,无论用何种方法,您必须拿到这些数据。
转自http://www.ibm.com/developerworks/cn/java/j-perf09024.html
分享到:
相关推荐
ROC(Receiver Operating Characteristic)曲线是评估二分类模型性能的重要工具,尤其在图像处理和边缘检测领域中广泛应用。本文将详细解析ROC曲线的概念、生成过程以及如何在MATLAB环境中使用它来评估边缘检测的...
边缘性能和边缘检测在计算机视觉、图像处理以及机器学习领域中扮演着至关重要的角色。边缘是图像中的一个重要特征,它们代表了图像亮度的显著变化,往往对应着物体的边界,因此,准确地检测和评估边缘对于图像分析和...
### SUSAN边缘检测算法性能分析与比较 #### 引言 边缘检测作为图像处理领域中的关键技术之一,在图像识别、图像分割、目标跟踪等应用中扮演着至关重要的角色。经典的边缘检测算法,例如Roberts、Sobel、Prewitt、...
在数字图像处理领域,边缘检测是至关重要的一步,它能够揭示图像中物体的轮廓和结构,对于后续的图像分析、识别和理解起到基础性作用。本课程设计的目标是对比和研究几种经典的边缘检测算子,包括基于一阶导数的...
"高性能边缘计算物联网"的主题涵盖了多个关键知识点,以下是对这些内容的详细阐述: 1. **边缘计算的基本概念**:边缘计算是在物联网设备和云之间构建的一种计算架构,它通过在网络边缘部署计算资源来处理和存储...
6. **分析结果**:根据生成的数据和报告,分析边缘计算系统的性能和优化空间。 边缘计算的研究和应用领域广泛,包括物联网(IoT)、自动驾驶、实时视频流处理、工业自动化等。通过iFogSim这样的仿真工具,开发者和...
MATLAB提供了性能分析工具,可以对算法进行基准测试和比较。 6. 代码生成与部署:MATLAB的Code Generation功能可以将模型转化为C/C++代码,便于在嵌入式系统或边缘设备上直接运行,降低了软件移植的难度。 文件...
### 边缘计算场景下的对象存储与分析 #### 一、边缘计算场景对对象存储的要求 **1. 高容量与弹性扩展** - **高容量存储能力**:边缘计算环境中产生的数据量巨大,因此对象存储系统需要具备强大的存储能力来满足这...
- **医疗健康**:可穿戴设备通过边缘AI技术实时分析用户健康数据,提供即时反馈。 - **自动驾驶**:车辆上的摄像头和雷达系统利用边缘计算进行实时环境感知和决策制定。 #### 三、关键技术与工具 ##### 1. **硬件...
在图像处理中,边缘检测对于目标识别、图像分割、形状分析等任务至关重要。本文将深入探讨一种特殊的边缘检测方法——基于蚁群聚类算法的图像边缘检测,以及MATLAB在实现这一算法中的应用。 首先,让我们了解边缘...
通过研究这个项目,你可以了解如何准备数据、构建UNet模型、训练模型、评估模型性能以及如何应用模型进行细胞边缘检测。这不仅有助于提升你的深度学习技能,还可能启发你在其他领域应用UNet模型,例如医疗影像分析、...
SUSAN边缘检测算法是一种高效的图像处理技术,主要用于识别图像中的边缘特征,它在处理噪声图像时表现出极强的...总的来说,SUSAN边缘检测算法在互联领域和其他需要边缘检测的图像处理任务中,是一种高效且实用的工具。
4. **边缘细化**:边缘检测后,可能会出现断裂或重叠的边缘,需要通过连通成分分析、边缘细化等操作来修复和优化边缘。 5. **应用到车牌识别**:在车牌识别系统中,边缘检测后的结果会被进一步处理,如轮廓检测、...
1. **小波变换**:小波变换是一种多尺度分析工具,可以用于提取图像中的不同尺度特征。在边缘检测中,小波变换可以帮助区分不同尺度的边缘信息,从而实现更精细的边缘提取。 2. **数学形态学**:数学形态学是一套...
小波分析是一种数学工具,它能够同时处理信号的时间和频率信息。小波函数具有局部化特性,可以对信号进行多尺度分析,这意味着可以精细地观察信号的不同细节层次。在图像处理中,小波分析可以将图像分解为不同分辨率...
- **本地数据处理**:边缘计算设备靠近数据源,能够快速处理和分析数据,减轻云端服务器负担,实现更高效的资源分配。 - **应用程序部署**:在边缘设备上部署应用程序减少了数据向云端传输的需求,降低了带宽成本...
这些服务包括但不限于计算、存储、数据库、分析工具等,可以根据用户的需求进行灵活扩展。云基础设施的主要特征包括: - **虚拟化**:通过虚拟化技术将物理资源抽象化,提高资源利用率。 - **可扩展性**:用户可以...
- **小波变换**:小波变换则是一种多分辨率分析工具,它可以对图像进行多尺度分解,从而更好地捕捉不同尺度下的细节信息。这种方法特别适合于处理图像中的边缘和纹理等复杂结构。 结合这两种方法的优势,提出的算法...
1. **小波变换**:小波变换是图像处理中常用的一种工具,它能够将信号或图像在不同尺度和位置上进行分析。与傅立叶变换相比,小波变换具有时频局部性,即能在时间和频率域同时提供信息,这对检测图像中的边缘非常...