找不到内存泄漏 [英] Cannot find the memory leak
问题描述
我一直在WP7的应用程序,它的图片库的应用程序,以实现基本的缩放和快速滑动手势。
I have been working on a WP7 app, it's image gallery app, with basic zooming and flick gestures implemented.
为了测试我的编译应用程序离线图像(其文件名的编号)设置为内容,并通过硬codeD串访问它们(稍后将取代)。
For test purposes I compiled the app with offline images(their filenames are numbered) set to Content and accessed them via hard coded string (which will be replaced later).
但感悟到应用消耗了大量的内存。我认为这是由于图像,发现<一个href=\"http://blogs.msdn.com/b/swick/archive/2012/04/05/10151249.aspx?CommentPosted=true#commentmessage\"相对=nofollow>这个博客;图像始终缓存。我用code从博客进行整治。内存仍然没有被释放,虽然消费率没有下降。
But came to realize that app consumes a lot of memory. I thought it was due to images and found this blog; images were always caching. I used the code from the blog to rectify this. Still memory is not released, although rate of consumption did go down.
有关最后一次尝试,我创建了基本的功能按键2另一个测试的应用程序为图像导航和图像控制,只是为了确保这不是我的手势codeS,可能是这个问题。
For final attempt I created another test app with basic feature 2 button for navigation and image control for images, just to make sure it was not my gesture codes that could be the problem.
这是XAML
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Grid.Row="0" x:Name="ImageHolder" Height="Auto" Width="Auto" Stretch="Uniform" Tap="image_Tap" />
<TextBlock x:Name="MemUsage" />
<StackPanel Grid.Row="1" Orientation="Horizontal">
<Button x:Name="PrevButton" Content="Prev" Width="240" Click="btnPrev_Click"/>
<Button x:Name="NextButton" Content="Next" Width="240" Click="btnNext_Click"/>
</StackPanel>
</Grid>
这是cs文件
const int PAGE_COUNT = 42;
int pageNum = 0;
public MainPage()
{
InitializeComponent();
RefreshImage();
}
private void btnPrev_Click(object sender, RoutedEventArgs e)
{
pageNum = (PAGE_COUNT + pageNum - 1) % PAGE_COUNT; // cycle to prev image
RefreshImage();
}
private void btnNext_Click(object sender, RoutedEventArgs e)
{
pageNum = (PAGE_COUNT + pageNum + 1) % PAGE_COUNT; // cycle to next image
RefreshImage();
}
private void image_Tap(object sender, GestureEventArgs e)
{
RefreshTextData();
}
private void RefreshImage()
{
BitmapImage image = ImageHolder.Source as BitmapImage;
ImageHolder.Source = null;
if (image != null)
{
image.UriSource = null;
image = null;
}
ImageHolder.Source = new BitmapImage(new Uri("000\\image" + (pageNum + 1).ToString("D3") + ".jpg", UriKind.Relative));
RefreshTextData();
}
private void RefreshTextData()
{
MemUsage.Text = "Device Total Memory = " + (long)DeviceExtendedProperties.GetValue("DeviceTotalMemory") / (1024 * 1024)
+ "\nCurrent Memory Usage = " + (long)DeviceExtendedProperties.GetValue("ApplicationCurrentMemoryUsage") / (1024 * 1024)
+ "\nPeak Memory Usage = " + (long)DeviceExtendedProperties.GetValue("ApplicationPeakMemoryUsage") / (1024 * 1024);
}
但还是内存泄漏是存在的,我不能针点吧。我有一个很难找到它。内存探查表明,我有一个字符串的多个实例,我不能跨preT这一点。
But still memory leak is there and I can't pin point it. I am having a hard time finding it. Memory profiler shows that I have many instances of a string, and I can't interpret that.
几点:
- 我有一个文件夹000,并命名为图像###形象。在present我有一个文件名的图片来自image001到image042
- 测试应用程式一旦具有6 MB存储器足迹,因为它示出了第一页完全与图像,并经过最前一页页改变它上升到几乎18-20 MB
- 后续页面变更结果在内存逐渐增加,然后最终崩溃,如果图像的数量允许通过的所有图像内存消耗循环后否则是恒定
- 我使用.jpg文件与尺寸约1280 * 2000,测试我不调整图像大小。
推荐答案
我有同样的应用程序,下/ previous图片按钮。和我完全一样的内存泄漏,这推动了我疯了。
I have the same kind of app, with the next/previous picture buttons. And I had exactly the same memory leak, which has driven me mad.
我还没有能够找到问题的根源,但我已经成功了丑陋的黑客绕过它。当显示下一个画面,我对旧图像源加载一个无效的图片,从而释放内存。我不明白为什么删除所有引用,并调用垃圾收集器是不够的,必须有另一个参考保持内部的某个地方。
I still haven't been able to find the root cause, but I've managed to bypass it with a ugly hack. When displaying the next picture, I force the old image source to load an invalid picture, thus freeing the memory. I don't understand why removing all references and calling the garbage collector isn't enough, there must be another reference kept internally somewhere.
总之,这里是黑客:
private void DisposeImage(BitmapImage image)
{
if (image != null)
{
try
{
using (var ms = new MemoryStream(new byte[] { 0x0 }))
{
image.SetSource(ms);
}
}
catch (Exception)
{
}
}
}
您可以在 RefreshImage
方法调用它,例如:
You can call it for instance in your RefreshImage
method:
private void RefreshImage()
{
BitmapImage image = ImageHolder.Source as BitmapImage;
ImageHolder.Source = null;
DisposeImage(image);
ImageHolder.Source = new BitmapImage(new Uri("000\\image" + (pageNum + 1).ToString("D3") + ".jpg", UriKind.Relative));
RefreshTextData();
}
均田羞于使用,但至少它似乎工作。
Kinda ashamed to use that, but at least it seems to work.
这篇关于找不到内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!