1

仪器屏幕截图

我很难理解为什么这会消耗内存。

我试过了;

  1. 让 ARC 有更多时间进行清理
  2. 创建要传递的全局变量的 __weak 副本
  3. 看着使用 __bridge 或 __bridge_transfer 但我不认为这是合适的。
  4. 公开全局变量并直接引用它(有效,但不切实际)

这个 iOS 目标 c 线程是通过 j2objc 0.9.3 从 Java 应用程序翻译的。

@implementation Comms_StatusThread

- (void)run {
while (true) {

    // Consumes memeory at aproximately 100k per 5 min
    [S globals];

    @try {
        [JavaLangThread sleepWithLong:10];
    }
    @catch (JavaLangInterruptedException *e) {
    }
}

这个翻译后的静态单例存储“全局”,可以从应用程序的任何地方访问(真实代码存储更多的类和回调)。

@implementation S

Globals * S_globals__ = nil;

+ (Globals *)globals {
    {
        if (S_globals__ == nil) S_globals__ = [[Globals alloc] init];
        return S_globals__;
    }
}

@end

任何帮助表示赞赏。我是objective-c和ARC的新手。我已经阅读了大量关于 ARC 的内容,但仍然不明白这种内存消耗的原因。


感谢学生 TI 尝试了以下方法。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(test:) userInfo:nil repeats:YES];
    return YES;
}

-(void) test: (NSObject*) o {
    [S comms];
    [S globals];
}

这不会消耗内存,我打算这样做,但是tball 的新答案(使用 j2objc @AutoreleasePool)显然是最好的选择,所以我将从那里开始。

非常感谢您的所有回答!

4

3 回答 3

2

S_globals 不是静态的;它很明显缺少静态修饰符关键字。所以你每次循环时都会创建一个新的,这是不断发生的。

坦率地说,那个代码是可怕的。帮大家一个忙,不要使用 Java 翻译器。

于 2014-08-29T04:47:13.820 回答
1

如果需要编写一个不断创建对象的循环,那么无论是否使用 ARC,内存都会增长。ARC 中的“A”是“自动的”,因为它的目的是自动使用保留/释放/自动释放方法。这些方法不会随 ARC 消失,它们只是由编译器而不是开发人员处理。

j2objc 为长寿命对象(如线程池执行器、单元测试运行器和基准测试)添加的是AutoreleasePool注释,它(毫不奇怪)生成“@autoreleasepool { ... }”。此注解可用于方法和 for 循环变量声明(在 Java 7 中不能用于其他地方,因为注解需要声明,但我们将能够改进对 Java 8 的支持)。由于创建和清空自动释放池会损害性能,因此请选择大小合理的工作“块”,例如以下示例:

public void run() { while (true) { for (@AutoreleasePool int i = 0; i < 10000; i++) { S.globals(); } } }

只要您的心愿意,您应该能够运行它而不会耗尽内存。

于 2014-08-29T17:23:50.203 回答
0

假设您正在使用 ARC 进行编译,因为如果您不是,那么整个转换将毫无意义。您的实验无法进行,因为您将代码置于无限循环中。您试图使线程休眠,但它不起作用,因为您同时也停止了正在运行的主线程。您需要让主运行循环有机会在 10 秒内运行。

于 2014-08-29T04:54:00.663 回答