GeneralBlock-56 在 UIWebView 中调用 loadRequest 时内存泄漏

发布于 2024-10-27 11:56:06 字数 843 浏览 2 评论 0原文

我正在开发一个 iPad 应用程序,并使用 XCode 4 中的 Instruments 对其进行分析。 我正在对实际设备本身进行分析。 iOS 4.3 已安装。

Instruments 告诉我有一些内存泄漏,泄漏的对象主要是 GeneralBlock-56 对象和一些 GeneralBlock-1024/GeneralBlock-8192 对象。 有趣的是,只有当我在应用程序中嵌入的 UIWebView 中加载 URL 时,才会报告这些泄漏。如果我注释掉 loadRequest 调用,这些泄漏就会消失。这种行为是一致可重现的。

loadRequest() 调用如下所示:

[webPage loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://slashdot.org"]]];

顺便说一句,我没有为此 UIWebView 指定任何委托。 泄漏没有显示任何负责任的库/负责任的框架,并且最右边的框架中没有扩展细节。

我尝试摆弄 NSURLCache 设置,如下所示:

NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
[sharedCache release];

这减少了一些 GeneralBlock 内存泄漏,但仍有一些泄漏。 非常欢迎对此行为的任何见解...谢谢!

I'm working on an IPad app and have been profiling it using Instruments in XCode 4.
I'm profiling on the actual device itself. iOS 4.3 is installed.

Instruments tells me I have some memory leaks, the leaked objects being mainly GeneralBlock-56 ones and some GeneralBlock-1024/GeneralBlock-8192 ones.
The interesting thing is that these leaks are reported only when I load up a URL in a UIWebView embedded in my app. If I comment out the loadRequest call, these leaks go away. This behavior is consistently reproducible.

The loadRequest() calls looks like this:

[webPage loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://slashdot.org"]]];

I'm not specifying any delegates for this UIWebView, by the way.
The leaks do not show any Responsible Library/Responsible Frame and there is no Extended Detail in the rightmost frame.

I have tried to fiddle around with the NSURLCache settings, like so:

NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
[sharedCache release];

This reduces a few of the GeneralBlock memory leaks, but some still remain.
Any insights on this behavior are very welcome...thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

素染倾城色 2024-11-03 11:56:06

这是我使用 Apple 开发者错误报告工具提交的错误报告。在我的案例中,这似乎是导致内存泄漏的大问题之一。

摘要:将格式不正确的 NSURL 传递给 NSData dataWithContentsOfURL:会导致 createCanonicalURL() 方法中的内存泄漏。

重现步骤

在任何简单的项目中,将以下行放入控制器中,例如例如,在 loadView: 或 viewDidLoad: 方法中:

NSURL* u = [NSURL URLWithString:@"http:/portalqa01:70/Images/Leading%20out%20of%20a%20Downturn%20-%20Article%20Illustration%20-%20Large_tcm137-38905.gif"];
    NSData* data = [NSData dataWithContentsOfURL:u options:0 error:nil];

请注意,URL 在“http:”后面只有一个斜杠,而不是通常的两个斜杠。

预期结果:不应有任何内存泄漏。

实际结果:仪器显示内存泄漏。

回归:
这只发生在某些格式错误的 URL 上,上面的 URL 是一个具体示例。像“http://blah/blah.png”这样的 URL 不会导致泄漏。
用于重现此情况的环境是:

  • iPad 4.3 Simulator
  • iPad 2 with iOS 4.3.1

注意:
堆栈跟踪如下:

STACK TRACE START

   0 CFNetwork createCanonicalURL
   1 CFNetwork HTTPProtocol::_createMutableCanonicalRequest(__CFAllocator const*, _CFURLRequest const*, void const*)
   2 CFNetwork HTTPProtocol::_createCanonicalRequest(__CFAllocator const*, _CFURLRequest const*, void const*)
   3 CFNetwork HTTPProtocol::copyCanonicalRequest()
   4 CFNetwork URLConnectionLoader::copyProtocolCanonicalRequest()
   5 CFNetwork URLConnectionClient::getRequestForTransmission(unsigned char, _CFURLResponse*, _CFURLRequest const*, __CFError**)
   6 CFNetwork URLConnectionClient::_clientWillSendRequest(_CFURLRequest const*, _CFURLResponse*, URLConnectionClient::ClientConnectionEventQueue*)
   7 CFNetwork URLConnectionClient::ClientConnectionEventQueue::processAllEventsAndConsumePayload(XConnectionEventInfo<XClientEvent, XClientEventParams>*, long)
   8 CFNetwork URLConnectionClient::processEvents()
   9 CFNetwork MultiplexerSource::perform()
  10 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
  11 CoreFoundation __CFRunLoopDoSources0
  12 CoreFoundation __CFRunLoopRun
  13 CoreFoundation CFRunLoopRunSpecific
  14 CoreFoundation CFRunLoopRunInMode
  15 CFNetwork CFURLConnectionSendSynchronousRequest
  16 Foundation +[NSURLConnection sendSynchronousRequest:returningResponse:error:]
  17 Foundation -[NSData(NSData) initWithContentsOfURL:options:error:]
  18 Foundation +[NSData(NSData) dataWithContentsOfURL:options:error:]
  19 MemLeakTester -[MemLeakTesterViewController viewDidLoad] /Users/admin/IPadSpikes/MemLeakTester/MemLeakTester/MemLeakTester/MemLeakTesterViewController.m:36
  20 UIKit -[UIViewController view]
  21 UIKit -[UIWindow addRootViewControllerViewIfPossible]
  22 MemLeakTester -[MemLeakTesterAppDelegate application:didFinishLaunchingWithOptions:] /Users/admin/IPadSpikes/MemLeakTester/MemLeakTester/MemLeakTester/MemLeakTesterAppDelegate.m:27
  23 UIKit -[UIApplication _callInitializationDelegatesForURL:payload:suspended:]
  24 UIKit -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:]
  25 UIKit -[UIApplication handleEvent:withNewEvent:]
  26 UIKit -[UIApplication sendEvent:]
  27 UIKit _UIApplicationHandleEvent
  28 GraphicsServices PurpleEventCallback
  29 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__
  30 CoreFoundation __CFRunLoopDoSource1
  31 CoreFoundation __CFRunLoopRun
  32 CoreFoundation CFRunLoopRunSpecific
  33 CoreFoundation CFRunLoopRunInMode
  34 UIKit -[UIApplication _run]
  35 UIKit UIApplicationMain
  36 MemLeakTester main /Users/admin/IPadSpikes/MemLeakTester/MemLeakTester/MemLeakTester/main.m:14
  37 MemLeakTester start

STACK TRACE END

This is a bug report I filed with the Apple Developer Bug Reporting tool. This seemed to be one of the big issues causing the memory leak in my case.

Summary: Passing incorrectly formatted NSURL to NSData dataWithContentsOfURL: causes memory leak in createCanonicalURL() method.

Steps to Reproduce

In any simple project, put the following lines in your controller, for example, in loadView: or viewDidLoad: methods.:

NSURL* u = [NSURL URLWithString:@"http:/portalqa01:70/Images/Leading%20out%20of%20a%20Downturn%20-%20Article%20Illustration%20-%20Large_tcm137-38905.gif"];
    NSData* data = [NSData dataWithContentsOfURL:u options:0 error:nil];

Note that the URL has only a single slash after "http:" instead of the customary two.

Expected Results: There shouldn't be any memory leak.

Actual Results: Instruments shows a memory leak.

Regression:
This only occurs for some malformed URLs, the URL above is a specific example. A URL like "http:/blah/blah.png" will not cause a leak.
The environments used to reproduce this were:

  • iPad 4.3 Simulator
  • iPad 2 with iOS 4.3.1

Notes:
The stack trace is as below:

STACK TRACE START

   0 CFNetwork createCanonicalURL
   1 CFNetwork HTTPProtocol::_createMutableCanonicalRequest(__CFAllocator const*, _CFURLRequest const*, void const*)
   2 CFNetwork HTTPProtocol::_createCanonicalRequest(__CFAllocator const*, _CFURLRequest const*, void const*)
   3 CFNetwork HTTPProtocol::copyCanonicalRequest()
   4 CFNetwork URLConnectionLoader::copyProtocolCanonicalRequest()
   5 CFNetwork URLConnectionClient::getRequestForTransmission(unsigned char, _CFURLResponse*, _CFURLRequest const*, __CFError**)
   6 CFNetwork URLConnectionClient::_clientWillSendRequest(_CFURLRequest const*, _CFURLResponse*, URLConnectionClient::ClientConnectionEventQueue*)
   7 CFNetwork URLConnectionClient::ClientConnectionEventQueue::processAllEventsAndConsumePayload(XConnectionEventInfo<XClientEvent, XClientEventParams>*, long)
   8 CFNetwork URLConnectionClient::processEvents()
   9 CFNetwork MultiplexerSource::perform()
  10 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
  11 CoreFoundation __CFRunLoopDoSources0
  12 CoreFoundation __CFRunLoopRun
  13 CoreFoundation CFRunLoopRunSpecific
  14 CoreFoundation CFRunLoopRunInMode
  15 CFNetwork CFURLConnectionSendSynchronousRequest
  16 Foundation +[NSURLConnection sendSynchronousRequest:returningResponse:error:]
  17 Foundation -[NSData(NSData) initWithContentsOfURL:options:error:]
  18 Foundation +[NSData(NSData) dataWithContentsOfURL:options:error:]
  19 MemLeakTester -[MemLeakTesterViewController viewDidLoad] /Users/admin/IPadSpikes/MemLeakTester/MemLeakTester/MemLeakTester/MemLeakTesterViewController.m:36
  20 UIKit -[UIViewController view]
  21 UIKit -[UIWindow addRootViewControllerViewIfPossible]
  22 MemLeakTester -[MemLeakTesterAppDelegate application:didFinishLaunchingWithOptions:] /Users/admin/IPadSpikes/MemLeakTester/MemLeakTester/MemLeakTester/MemLeakTesterAppDelegate.m:27
  23 UIKit -[UIApplication _callInitializationDelegatesForURL:payload:suspended:]
  24 UIKit -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:]
  25 UIKit -[UIApplication handleEvent:withNewEvent:]
  26 UIKit -[UIApplication sendEvent:]
  27 UIKit _UIApplicationHandleEvent
  28 GraphicsServices PurpleEventCallback
  29 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__
  30 CoreFoundation __CFRunLoopDoSource1
  31 CoreFoundation __CFRunLoopRun
  32 CoreFoundation CFRunLoopRunSpecific
  33 CoreFoundation CFRunLoopRunInMode
  34 UIKit -[UIApplication _run]
  35 UIKit UIApplicationMain
  36 MemLeakTester main /Users/admin/IPadSpikes/MemLeakTester/MemLeakTester/MemLeakTester/main.m:14
  37 MemLeakTester start

STACK TRACE END

半暖夏伤 2024-11-03 11:56:06

我遇到了同样的问题。我仍在尝试验证这一点,但我最初的观察是,它只发生在提供 javascript 的网站上。你观察过这种模式吗?

I am experiencing the same issue. I am still trying to verify this, but my initial observation is that it only occurs with sites that are serving javascript. Have you observed this pattern?

双手揣兜 2024-11-03 11:56:06

尝试

[webView loadHTMLString: @"" baseURL: nil];

在释放 webview 之前添加。对于 4.2.1 中与在 UIWebView 中显示 PDF 相关的泄漏,这为我解决了大部分泄漏问题。

Try adding

[webView loadHTMLString: @"" baseURL: nil];

right before you release the webview. For a leak in 4.2.1 relating to displaying a PDF in a UIWebView this solves most of the leak problems for me.

梦醒灬来后我 2024-11-03 11:56:06

好吧,我在 UIWebView 上也遇到了同样的问题 - iPad、iPad2、iPhone 上有一大堆泄漏(General-Block56 等)。最后,以下内容有所帮助:拒绝 Nib 文件和“viewDidLoad”方法。相反,我以编程方式在“loadView”中创建了 webview:

- (void)loadView 
{ 
    self.activityView = [[[UIActivityIndicatorView alloc]    initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray] autorelease];
    self.webView = [[UIWebView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
    [self.webView addSubview: self.activityView];
    self.webView.scalesPageToFit = YES;
    self.view = self.webView;
    [self addGestures];
} 

- (void)viewWillAppear:(BOOL)animated 
{ 
      self.webView.delegate = self;
      [self.webView loadRequest:[self urlRequest]];
      [super viewWillAppear:animated];

}

最后,在开始加载第一页后,只剩下一个小泄漏(16 字节)。所有其他页面均已加载,没有任何泄漏。希望这有帮助。

Well, I had the same issue with UIWebView - a whole bunch of leaks (General-Block56 etc) on iPad, iPad2, iPhone. Finally the following helped: reject the Nib-file and the method 'viewDidLoad'. Instead of this I've created the webview in 'loadView' programmatically:

- (void)loadView 
{ 
    self.activityView = [[[UIActivityIndicatorView alloc]    initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray] autorelease];
    self.webView = [[UIWebView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
    [self.webView addSubview: self.activityView];
    self.webView.scalesPageToFit = YES;
    self.view = self.webView;
    [self addGestures];
} 

- (void)viewWillAppear:(BOOL)animated 
{ 
      self.webView.delegate = self;
      [self.webView loadRequest:[self urlRequest]];
      [super viewWillAppear:animated];

}

At the end there's only one small leak remaining (16 bytes) right after start loading the very first page. All other pages did load without any leak. Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文