本文通过几个示例来说明一些开发中的问题。首先看一下配置选项:
视图 |
描述 |
Histogram Allocated Types |
给你一个高等级的视图,它指出对象类型(分配的大小)在你的应用程序的生命周期内被分配的情况。这个视图也显示那些被分配在大对象堆(对象超过85KB)中的对象。 这个视图允许你点击图标的各个部分,为了你能看见哪些方法分配了哪些对象。 |
Histogram Relocated Types |
显示已被GC(重新)分配(位置)的对象,因为他们在一次GC后存活了下来(就是别人还引用他们) |
Objects By Address |
提供一个任意特定时间(at a given time)托管堆情况的图片 |
Allocation Graph |
用图表显示调用的堆栈是如何分别的对象。你能使用的视图有: *查看方法的分配成本(the cost of each alloction) *隔离你不期望的分配 *找出有可能过度分配的方法 |
Assemby,Module,Function,and Class Graph |
有4个非常相仿的视图。他们允许你看哪些方法涉及到了哪些程序集、类、模块、方法 |
Heap Graph |
显示托管堆上所有对象,以及他们的关联信息。 |
Call Graph |
使你查看哪些方法调用了哪些别的方法和多少频率。 你能使用这个图表摸索着了解类库的调用成本并判定调用这个方法的需求量和哪些方法被调用。 |
Time Line |
显示GC的在你的应用程序中的重新分配情况(就是那些么有被清楚的对象)。使用这个视图去: *研究了解GC的行为 *判定在3代中有多少GC发生(0,1,2代),和发生频率。 *判定哪些对象在GC后存活,被提升到了下一代。 你能选择时间点或间隔(intervals),通过右击去显示在这个时间间隙内(interval)谁分配了内存。 |
Call Tree View |
提供一个你应用程序执行的视图,它是基于文本按年代分级。使用这个视图可以: *查看什么类型被分配及他们的大小 *查看哪些程序集因方法调用而被被加载 *分析终结(finalizer)的使用,和他们的执行次数 *识别(indentify)方法在哪些地方没有使用"close"或"dispose",从而引发瓶颈。 *分析在你意料之外的分配。 |
1、 string和StringBuilder谁更快?
首先,建立测试环境,对字符串进行10000万次连接
using System;
using System.Collections.Generic;
using System.Text;
namespace StringTest
{
/// <summary>
/// Test String
/// </summary>
class Program
{
static void Main(string[] args)
{
string str = string.Empty;
for (int k = 0; k < 10000; k++)
str += k.ToString();
}
}
}
其中总共分配了大约379M内存,进行了119次的o代回收。接下来我们再看看字符串的内存分配情况,
点击上图中的Allocation Graph如下图:
我们再来看StringBuilder同样做10000次串联接
总分配内存为540,146 Final Heap Type 也是540,146说明是同一对象没有被GC回收。
再看,