- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在压缩字节,然后在解压缩时再次出现 OOM 异常。当我有足够的内存来存储它时,我无法理解为什么会出现此错误。
数据压缩后约20MB左右,待解压。但我总是遇到 OutOfMemory 异常。
下面是相同的代码。
public byte[] Compress(byte[] data)
{
byte[] compressArray = null;
try
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (DeflateStream deflateStream = new DeflateStream(memoryStream, CompressionMode.Compress))
{
deflateStream.Write(data, 0, data.Length);
deflateStream.Close();
}
compressArray = memoryStream.GetBuffer();
memoryStream.Dispose();
}
}
catch (Exception exception)
{
LogManager.LogEvent(EventLogEntryType.Error, exception.Message);
return data;
}
finally { GC.Collect(); }
return compressArray;
}
public static byte[] Decompress_Bytes(byte[] data)// Around 20MB data
{
byte[] decompressedArray = null;
try
{
using (MemoryStream decompressedStream = new MemoryStream())
{
using (MemoryStream compressStream = new MemoryStream(data))
{
using (DeflateStream deflateStream = new DeflateStream(compressStream, CompressionMode.Decompress))
{
deflateStream.CopyTo(decompressedStream);// Exception thrown at this line.
deflateStream.Close();
}
compressStream.Dispose();
}
decompressedArray = decompressedStream.GetBuffer();
decompressedStream.Dispose();
}
}
catch (Exception exception)
{
return data;
}
finally { GC.Collect(); }
return decompressedArray;
}
为了更好地理解,下面是堆栈跟踪。
at System.IO.MemoryStream.set_Capacity(Int32 value)
at System.IO.MemoryStream.EnsureCapacity(Int32 value)
at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.Stream.InternalCopyTo(Stream destination, Int32 bufferSize)
at System.IO.Stream.CopyTo(Stream destination)
at Symtrax.SQConsole.ConsoleConnectClass.Decompress_Bytes(Byte[] data) in c:\Developement\BI\branch_5.0\MapDesignerUNICODE\ConsoleConnector\SQConsole\ConsoleConnectClass.cs:line 3710
我发现了很多与此相关的问题,但似乎没有一个能解决我的问题。
由于我的声望点数较少,我无法发表评论。因此不得不发布问题。提前致谢。
最佳答案
如评论中所述,您将使用具有不同长度特征的 GetBuffer
获取内部缓冲区,然后只需调用 ToArray
。
我在您的代码中添加了一些转储语句,以便 LINQPad 可以揭示正在发生的事情:
public byte[] Compress(byte[] data)
{
byte[] compressArray = null;
data.Length.Dump("initial array length");
try
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (DeflateStream deflateStream = new DeflateStream(memoryStream, CompressionMode.Compress))
{
deflateStream.Write(data, 0, data.Length);
deflateStream.Close();
}
memoryStream.GetBuffer().Length.Dump("buffer compress len");
compressArray = memoryStream.ToArray();
compressArray.Length.Dump("compress array len");
// no need to call Dispose, using does that for you
//memoryStream.Dispose();
}
}
catch (Exception exception)
{
exception.Dump();
return data;
}
finally { GC.Collect(); }
return compressArray;
}
public static byte[] Decompress_Bytes(byte[] data)// Around 20MB data
{
byte[] decompressedArray = null;
try
{
using (MemoryStream decompressedStream = new MemoryStream())
{
using (MemoryStream compressStream = new MemoryStream(data))
{
using (DeflateStream deflateStream = new DeflateStream(compressStream, CompressionMode.Decompress))
{
deflateStream.CopyTo(decompressedStream);// Exception thrown at this line.
deflateStream.Close();
}
// no need, using does that
//compressStream.Dispose();
}
decompressedStream.GetBuffer().Length.Dump("buffer decompress len");
decompressedArray = decompressedStream.ToArray();
decompressedArray.Length.Dump("decompress array len");
// no need, using does that
decompressedStream.Dispose();
}
}
catch (Exception exception)
{
exception.Dump();
return data;
}
finally { GC.Collect(); }
return decompressedArray;
}
这是输出:
初始数组长度248404
缓冲区压缩长度262144
压缩数组长度189849
缓冲区解压长度327680
解压数组len248404
正如您从这些数字中看到的,您的长度计数会有很大不同。如果 Deflate 协议(protocol)允许具有额外字节的字节流,那么您可以摆脱那些额外的字节。
使用 GetBuffer
而不是 ToArray
似乎是有益的,但我希望复制最终数组所需的内存分配和 CPU 滴答可以忽略不计,特别是如果无论如何处理内存流。这个事实实际上减少了一点内存占用。
如果您仍然坚持重新使用内存流缓冲区,请确保也返回并提供缓冲区中的实际长度:
public byte[] Compress(byte[] data, out int len)
{
byte[] compressArray = null;
data.Length.Dump("initial array length");
try
{
using (MemoryStream memoryStream = new MemoryStream())
{
// keep the stream open, we need the length!
using (DeflateStream deflateStream = new DeflateStream(
memoryStream,
CompressionMode.Compress,
true))
{
deflateStream.Write(data, 0, data.Length);
deflateStream.Close();
}
// output length
len = (int) memoryStream.Length;
compressArray = memoryStream.GetBuffer();
}
}
catch (Exception exception)
{
exception.Dump();
len =-1;
return data;
}
finally { GC.Collect(); }
return compressArray;
}
public static byte[] Decompress_Bytes(byte[] data, ref int len)// Around 20MB data
{
byte[] decompressedArray = null;
try
{
using (MemoryStream decompressedStream = new MemoryStream())
{
// use the overload that let us limit the memorystream buffer
using (MemoryStream compressStream = new MemoryStream(data,0, len))
{
// keep the stream open
using (DeflateStream deflateStream = new DeflateStream(
compressStream,
CompressionMode.Decompress,
true))
{
deflateStream.CopyTo(decompressedStream);// Exception thrown at this line.
deflateStream.Close();
}
}
// output length
decompressedArray = decompressedStream.GetBuffer();
len = (int) decompressedStream.Length;
}
}
catch (Exception exception)
{
exception.Dump();
return data;
}
finally { GC.Collect(); }
return decompressedArray;
}
如果你使用上面的代码,你可以这样调用它:
int len;
var cmp = Compress(Encoding.UTF8.GetBytes(sb.ToString()), out len);
var dec = Decompress_Bytes(cmp,ref len);
注意使用 dec
中的字节,您只需要考虑第一个 len
字节数。实际上,这是通过使用 Array.Copy
来完成的,它打败了这个解决方案并将我们带回到调用 ToArray
的那个...
关于c# - 解压缩字节时抛出 System.OutOfMemory 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38321936/
我正在调查我们的应用程序运行缓慢的问题,最终导致集群环境中的一个实例出现故障。几周前我遇到了以下错误: [#|2012-05-11T14:12:03.460-0400|SEVERE|sun-appse
我创建了一个应用程序,基本上使用机器人在客户端获取图像并每隔几秒发送一次到服务器,这样我就可以看到另一台 PC 上发生了什么。问题似乎是它一直将图像保存在数组或其他东西中,因为几秒钟后,它崩溃了。我只
我正在使用 universal-image-loader-1.6.2.jar(最新的)。我正在尝试使用此库下载并缓存该图像。我要从服务器下载 47 张图片,总共 5.22 Mb。我的最大图片尺寸为 7
我在玩 Scala 的惰性迭代器,但遇到了一个问题。我想要做的是读取一个大文件,进行转换,然后写出结果: object FileProcessor { def main(args: Array[S
当涉及到服务器环境的垃圾收集/内存限制时,.Net 框架的行为是否可能有所不同?我在具有 32gbs 物理内存的 64 位服务器计算机上显式运行 x86 编译的应用程序,并且内存不足(SystemOu
在我的应用程序启动时,我正在创建具有 75*10^6 容量的长哈希集。 Profiler 显示,该应用程序使用 1.4g。我尝试设置-Xmx1600m,但发现内存不足。 -Xmx2000m 相同。 -
我有一项关于使用数字列表构建金字塔的任务,但一项测试存在一个问题。在我的任务中,我需要对列表进行排序。我使用 Collections.sort(): Collections.sort(inputNum
在对我为 Windows Mobile 编写的类库进行一些最终测试时(使用 Compact Net Framework 2.0),我遇到了 OOM 异常。 基本上,我的库首先加载一个字典文件(一个带有
编辑:我将其重新表述为问题并将答案移至答案部分... 在一个相对复杂的多线程 .NET 应用程序中,我遇到了 OutOfMemoryException,即使在我认为没有理由的情况下也是如此。 情况:
当我尝试使用下面的方法将一些文本内容设置到我们心爱的窗口的剪贴板时 片段,它在 10-15MB 的范围内工作正常。但是超过这个大小,它会抛出一条错误消息 显示在最后。我们如何将 30+ MB 的 ut
我想在 Android 中将 PDF 图像发送到服务器。 服务器规范需要我应该使用 Base64 编码。 所以我应该将 PDF 图像文件转换为 Base64 字符串。 下面是 HTTP POST 请求
我正在解析设备上的二进制文件并将我关心的字段存储在数组中。这些文件可以生成大小为 100,000 的数组。自然地,java 告诉我内存不足(我认为 android 每个应用程序只允许 16MB)。 还
我正在尝试从一个 txt 文件(书籍)中读取,然后将它的每一行添加到一个链表中。但是,当我运行代码时,我在 l.add(line); 处遇到内存不足错误。你能告诉我这段代码做错了什么吗?或者,是否有更
我通过允许用户选择要显示的图片从 SD 卡加载位图。创建位图后,我在 ImageView 中设置位图: mBitmap = Bitmap.createBitmap(Media.getBitmap(th
我试图在 gridview 中显示很多图像。有两个 Activity 。它们都有 gridviews,其中有图像。当我只启动其中一个时。没有问题,但是当我启动另一个时,存在“outifmemory”问
我需要在我的应用程序中显示许多图像。这些是 jpg 和 png,我将它们加载到 ImageView 中,如下所示: tile.setImageResource(R.drawable.tile_high
我正在开发一个远程备份应用程序,有时我需要上传大文件,例如 15 MB,我在一些手机上测试过我遇到内存不足的错误 有没有办法使用这个函数来使用更少的内存? public int uploadFile(
我在模拟器和设备(acer 平板电脑和三星 galaxy)上运行我的项目时出现 OutOfMemory 异常,显示 the application launcher process com.andro
我有一个程序可以为目录(子)树中的每个文件创建一个对象。在磁盘越来越大的今天,没有办法知道会有多少文件,尤其是。不是几年(几个月?)从现在开始。 我的程序不是企业关键的;它是用户分析该子树的工具。所以
我已经使用以下命令从命令行启动了我的jar java -Xms1200m -Xmx1500m -jar xxx.jar 我正在创建大小为 12600 * 12600 的 BufferedImage 意
我是一名优秀的程序员,十分优秀!