使用AppendBlob进行内存泄漏

时间:2017-01-26 09:54:50

标签: c# azure azure-storage-blobs

我正在使用DownloadText方法下载AppendBlob内容,我遇到了内存泄漏问题。它已经发生在任何人身上吗?我使用的代码:

    private string[] GetBlobLines(CloudAppendBlob blob)
    {
        string text = "";
        try
        {
            lock (_blobContainerLock)
            {
                text = blob.DownloadText();
            }
        }
        catch (Exception e)
        {
            WriteToTable(MessageType.ERROR, "Error reading log lines: " + e.Message);
        }

        return text.Split('\n'); ;
    }


    public string GetLastLogRows(uint count)
    {
        var sb = new StringBuilder();
        var blob = _currentBlob;

        int lineCount = 0;
        int blobOffset = 0;

        while (lineCount < count)
        {
            var lines = GetBlobLines(blob);
            var blobLineCount = lines.Count();

            var i = blobLineCount - 1;
            while ((lineCount < count) && (i > -1))
            {
                sb.AppendLine(lines[i--]);
                lineCount++;
            }

            if (lineCount < count)
            {
                blobOffset++;
                blob = _blobContainer.GetAppendBlobReference($"{BLOB_PREFIX}{_currentBlobIdx - blobOffset}");

                if (!blob.Exists())
                    break;
            }
        }

        return sb.ToString();
    }

1 个答案:

答案 0 :(得分:0)

根据我的理解,您存储的每个日志记录都附加一个换行符(\ n)。您可以利用GetLastLogRows从AppendBlob以相反的顺序检索特定的数字日志记录。要检索特定的日志记录,您需要下载整个AppendBlob文件。此时,随着日志内容大小的增加,内存泄漏是时间问题。您可以在调用CloudAppendBlob.DownloadText时使用Fiddler检查详细请求,或使用官方工具Microsoft Azure Storage Explorer检查AppendBlob文件的大小。

if (lineCount < count)
{
    blobOffset++;
    blob = _blobContainer.GetAppendBlobReference($"{BLOB_PREFIX}{_currentBlobIdx - blobOffset}");

    if (!blob.Exists())
        break;
}

如果我正确理解了上述代码,您将检查当前日志记录的数量是否小于count的所需参数GetLastLogRows时是否创建了新的AppendBlob文件。如果存在,则下载新创建的AppendBlob文件,并将日志记录与前一个AppendBlob文件中的记录组合在一起。此时,检索到的日志记录的顺序会中断。

正如我所知,追加blob针对追加操作进行了优化。我假设您可以利用Table Storage来存储日志。您可以按照issue设计PK和RK,然后使用TableQuery.Take从表存储中检索最新记录。您可以参考此document以更好地理解此方法。