2016-04-06 15 views
2

get için count değişken eşitlenmesini ve diğer üyelere göre ayar için özel bir yardımcı işlevini yapmaya çalışıyorum. Birden çok iş parçacığının her biri setCount()'u deadlineNoteVisible ve referencesAvailable olarak değiştiriyor. Sadece setCount() yöntemi için synchronized ile Android OutOfMemoryError: 16764448 serbest bayt ile 57993496 bayt ayırma atama başarısız oldu

, işler iyidir, ama ben get() çağrısına synchronized(this) eklerken, ben almak :

OutOfMemoryError: Failed to allocate a 57993496 byte allocation with 16764448 free bytes and 32MB until OOM 

Kodu (KOTLIN yazılmış):

var count: Int = 0 
    // Why does adding synchronized here explode? 
    get() = synchronized(this) { count } 
    private set 

private fun setCount() { 
    synchronized(this) { 
     count = 0 
     if (deadlineNoteVisible) { 
      count += 1 
     } 
     if (referencesAvailable) { 
      count += 1 
     } 
    } 
} 

Yığın izleme:

Error reporting crash 
java.lang.OutOfMemoryError: Failed to allocate a 57993496 byte allocation with 16764448 free bytes and 32MB until OOM 
    at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:95) 
    at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:125) 
    at java.lang.StringBuffer.append(StringBuffer.java:278) 
    at java.io.StringWriter.write(StringWriter.java:123) 
    at com.android.internal.util.FastPrintWriter.flushLocked(FastPrintWriter.java:358) 
    at com.android.internal.util.FastPrintWriter.appendLocked(FastPrintWriter.java:303) 
    at com.android.internal.util.FastPrintWriter.write(FastPrintWriter.java:625) 
    at com.android.internal.util.FastPrintWriter.append(FastPrintWriter.java:658) 
    at java.io.PrintWriter.append(PrintWriter.java:691) 
    at java.io.PrintWriter.append(PrintWriter.java:687) 
    at java.io.Writer.append(Writer.java:198) 
    at java.lang.Throwable.printStackTrace(Throwable.java:324) 
    at java.lang.Throwable.printStackTrace(Throwable.java:300) 
    at android.util.Log.getStackTraceString(Log.java:343) 
    at com.android.internal.os.RuntimeInit.Clog_e(RuntimeInit.java:61) 
    at com.android.internal.os.RuntimeInit.-wrap0(RuntimeInit.java) 
    at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:86) 
    at com.crashlytics.android.core.CrashlyticsUncaughtExceptionHandler.uncaughtException(CrashlyticsUncaughtExceptionHandler.java:249) 
    at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693) 
    at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690) 
+2

Yakalanmamış bir istisna atıldığında tetiklenen bir "crashlytics" kilitleme işleyicisine sahip olduğunuz ve yığın izlemeyi yazdırırken 55 MB'lık bir dize oluşturmaya çalıştığınız anlaşılıyor. Yakalanmamış istisnaları yakalayan bir hata ayıklayıcısını eklemek, en azından işleri başlatmaya yarayan çökmeyi tanımlamanızı sağlar. – fadden

+0

'Senkronize' yöntemi muhtemelen kırmızı-ringa balığıdır, sadece sızıntı yapan uygulamanın çok büyük olmasına neden olmuştur. Uygulamayı çalıştıran yoyr profilini okuyabilir ve neyin hafızaya geçtiğini öğrenebilir misin? – sisyphus

+0

Niçin bir okumayı niçin senkronize etmeniz gerekiyor? –

cevap

5

getCount()'u getCount() koşulsuz koşulsuz olarak aradığınız için bir StackOverflowError kullanıyorsunuz. Bunu sadece bir yazım hatası var ve kodu olmalıdır varsayalım:

var count: Int = 0 
    get() = synchronized(this) { field } 
    private set 

burada field tanımlayıcınızın mülkiyet bir destek alanını erişmesini sağlar. Destek alanlarıyla ilgili daha fazla bilgiyi here okuyabilirsiniz.