首页 \ 问答 \ 动态代理:如何处理嵌套方法调用(Dynamic Proxy: how to handle nested method calls)

动态代理:如何处理嵌套方法调用(Dynamic Proxy: how to handle nested method calls)

我正在尝试用Java学习动态代理。

我知道他们是如何工作但我无法找到解决我的问题的方法:给定一个接口及其实现方法a(),b()和c()嵌套到另一个(让我们说a()调用b( )它调用c()),我想代理我的对象来记录对方法的EACH调用。

所以我编写我的InvocationHandler,例如invoke()方法在执行之前打印一个日志行。

但是当我调用proxy.a()时,只记录方法a()的调用,而不是整个方法链。

我错过了什么? 代理的目标是否必须是代理本身?


I'm trying to learn Dynamic Proxies in Java.

I know how they work but I can't find a solution to my problem: given an interface and its implementation with methods a(), b() and c() nested one into the other (let's say a() calls b() which calls c()), I would like to proxy my object to log EACH call to the methods.

So I code my InvocationHandler such as the invoke() method prints a log-line before the execution.

But when I call proxy.a(), only the call of method a() is logged and not the whole chain of methods.

What am I missing? Is the target of the proxy have to be a proxy itself?


原文:https://stackoverflow.com/questions/9412004
更新时间:2023-10-22 16:10

最满意答案

我会对@autoreleaspool发表评论,以帮助你解决问题。

Apple建议使用@autoreleaspool来关注内存。 以下段落取自Core Data 文档 ,但我相信也可以应用于这种情况:

与许多其他情况一样,当您使用Core Data导入数据文件时,重要的是要记住适用Cocoa应用程序开发的“常规规则”。 如果导入必须以某种方式解析的数据文件,则可能会创建大量临时对象。 这些会占用大量内存并导致分页。 就像使用非Core Data应用程序一样,您可以使用本地自动释放池块来限制内存中驻留的其他对象数量。 有关Core Data和内存管理之间交互的更多信息,请参阅“减少内存开销”。

基本上,@ autoreleasepool用作编译器在一旦超出范围时释放所有临时对象的提示。 您期望完全释放内存,这可能不是Apple框架的情况。 窗帘后面可能会有一些缓存(这只是想法)。 这就是剩下的1MB可能没问题的原因。 但是,为了安全起见,我建议增加迭代次数,看看会发生什么。

正如您在评论中提到的,您的循环很大并且是嵌套的,因此可能还会发生其他事情。 尝试摆脱所有额外的操作,看看会发生什么。

希望这有帮助,干杯!


I'll make my comment on @autoreleaspool a legitimate answer to help you out.

Apple suggests to use @autoreleaspool where the memory is in concern. The following paragraph is taken from Core Data documentation, but I believe can be applied in this situation as well:

In common with many other situations, when you use Core Data to import a data file it is important to remember “normal rules” of Cocoa application development apply. If you import a data file that you have to parse in some way, it is likely you will create a large number of temporary objects. These can take up a lot of memory and lead to paging. Just as you would with a non-Core Data application, you can use local autorelease pool blocks to put a bound on how many additional objects reside in memory. For more about the interaction between Core Data and memory management, see “Reducing Memory Overhead.”

Basically, @autoreleasepool serves as a hint for a compiler to release all temporary objects once they are out of bounds. You're expecting for the memory to be released completely, which might not be the case with Apple frameworks. There might be some caching going in behind the curtains (This is just and idea). That is why that remaining 1MB may be ok. However, just to be safe, I would recommend to increase the iteration number and see what happens.

As you mentioned in your comment your loop is big and nested, so there might be something else going on. Try to get rid of all extra operations and see what happens.

Hope this helps, Cheers!

相关问答

更多
  • 我会对@autoreleaspool发表评论,以帮助你解决问题。 Apple建议使用@autoreleaspool来关注内存。 以下段落取自Core Data 文档 ,但我相信也可以应用于这种情况: 与许多其他情况一样,当您使用Core Data导入数据文件时,重要的是要记住适用Cocoa应用程序开发的“常规规则”。 如果导入必须以某种方式解析的数据文件,则可能会创建大量临时对象。 这些会占用大量内存并导致分页。 就像使用非Core Data应用程序一样,您可以使用本地自动释放池块来限制内存中驻留的其他对象 ...
  • 你在那个循环中创建了大量的临时对象; 如果它们中的一些最终出现在自动释放池中而不是明确地发布,那么它们会累积,因为你的循环中没有@autoreleasepool 。 严格来说,这不是内存泄漏本身(因为它最终将被释放),但它可能看起来像是仪器中的一个。 尝试重写一下你的循环,删除一些不必要的NSData对象。 例如: [ringBuffer didReadLength:allBytesAvailable]; const uint8_t *ptr = readPointer; const uint8_t *e ...
  • 当您访问NSData ,它经常被压缩(使用PNG或JPEG )。 当您使用UIImage ,有一个未压缩的像素缓冲区,通常每像素4个字节(分别为红色,绿色,蓝色和alpha的一个字节)。 还有其他格式,但它说明了JPEG或PNG表示可以压缩的基本思想,当您开始使用图像时,它是未压缩的。 在您的结论中,您说调整大小不是一个选项,并且NSData已经是7kb。 我建议如果图像的分辨率大于你正在使用它的UIImageView的分辨率( bounds / frame的点乘以设备的比例),则应该考虑调整大小。 是否调 ...
  • UIImage有一个 - initWithData:方法。 从文档:“数据参数中的数据必须格式化以匹配系统支持的图像类型之一的文件格式。 UIImage has an -initWithData: method. From the docs: "The data in the data parameter must be formatted to match the file format of one of the system’s supported image types."
  • NSData *imageData = UIImageJPEGRepresentation(image, 0.7); // 0.7 is JPG quality 要么 NSData *imageData = UIImagePNGRepresentation(image); 取决于您是否需要PNG格式或JPG格式的数据。 NSData *imageData = UIImageJPEGRepresentation(image, 0.7); // 0.7 is JPG quality or NSData * ...
  • 由于[bean image]实际上是图像数据的基本64编码,因此您需要使用一种方法将编码数据转换回未编码的数据。 没有标准的方法,但有很多你可以找到和使用。 然后你的代码变成这样: NSString *byteString = [bean image]; // no need for a cast if it's already an NSString NSData *byte = // call some method to convert base 64 encoded string into an N ...
  • 我注意到你的代码开始两个上下文但只结束一个。 这是我的扩展,基本上和你的一样。 由于我没有内存问题,看起来可能是问题所在。 extension UIImage { public func resizeToRect(_ size : CGSize) -> UIImage { UIGraphicsBeginImageContext(size) self.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size. ...
  • 试试这个代码。 NSURL* url = [NSURL URLWithString:@"http://imageAddress.com"]; NSURLRequest* request = [NSURLRequest requestWithURL:url]; [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLRespons ...
  • NSData较小,因为它存储图像的压缩版本。 但是, 解压缩需要时间 ,所以只要内存允许,缓存UIImage并在出现内存警告时清除缓存。 NSData is smaller because it stores the compressed version of the image. But decompressing takes time, so as long as memory allows, cache the UIImage and clean the cache if you get a memo ...
  • 好的,经过多次搜索,我们已经发现了解决方案(虽然我仍然没有对这个问题有一个非常深刻的理解,如果有人能指出我为什么会出现这个问题的正确方向,那就太好了) 。 所有需要做的就是在@autoreleasepool{}标记中包含使用此结果的代码行。 我从这个问题中找到了解决方案的基本思路 Okay, after much searching, the solution has been discovered (though I still do not have a very deep understanding ...

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)