Articles of memory leaks

为什么build议不要使用UI保留片段?

我用ui读取保留片段,并在视图上引用可能导致内存泄漏。 比我创buildtesting应用程序与片段,我存储一些参考视图和设置setRetaineInstance(true),但几个屏幕旋转不会导致任何泄漏。 MAT说我只有一个父活动的例子。 我做错了什么? 在哪些情况下用ui保留片段会导致泄漏? RetainInstanceActivity.java public class RetainInstanceActivity extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction() .add(android.R.id.content, RetainFragment.newInstance()) .commit(); } }} RetainFragment.java public class RetainFragment extends Fragment { private View mLogin; private View mPassword; private View ImageView; public static RetainFragment newInstance() { final RetainFragment fragment = […]

内存泄漏的实际例子

我一直在努力识别内存泄漏。 我想我的项目循环进度视图中有几个内存泄漏。 我的猜测之一是我有内部类FadeRunnable内存泄漏。 但说实话,我不知道如何确定这是否是问题的根源。 那么,当我做通常的情况下,切换方向,我看到增加的内存使用情况如下所示。 如果我注释掉FadeRunnable类的用法,步骤会更小( 但仍然存在,所以我想这不是唯一的泄漏 ) 一旦我分析堆转储,我看到一些东西。 但实际上我不知道这些价值是什么意思。 我做的事情是 多次改变方向 打开堆转储并按“保留大小” 现在当我点击“CircularProgressView”时,我在右边看到了8行,我想这意味着有8个“CircularProgressView”实例泄漏,并且在内存中孤立地存在。 它是否正确? 如果是这样,我怎么能find转储信息( 我猜在下面的窗格中的某个地方 )保存/保存此对象的位置。 我很想有一个一步一步的解释如何找出是否和哪个对象泄漏一些内存。 所有怀疑视图的代码都可以在这个类中find。 https://github.com/momentummodules/CircularProgressView/blob/master/circularprogressview/src/main/java/momentum/circularprogressview/CircularProgressView.java 但也可以随时查看完整的项目,以获得更深入的洞察力,如果你想玩它。 提前致谢! UPDATE 上面的代码链接显示了mem-leaking内部类的固定代码。 下面的代码片段显示了永远不会这样使用的原始的泄漏代码 /** * Mem-leaking code, for fixed code see repository link * https://github.com/momentummodules/CircularProgressView/blob/master/circularprogressview/src/main/java/momentum/circularprogressview/CircularProgressView.java */ public class CircularProgressView extends View { … private Thread fadeThread = null; … … class FadeRunnable […]

回收位图不释放内存

我有一个TabHost活动与其他3个活动。 因此,这些都是活着的(或处于“暂停”状态)。 第一个活动有四个不同的图像(每个〜250kb),他们正在检索大量的内存(大约80MB。只是指出,我加载屏幕所需的最小尺寸,如果有帮助,我使用layout_weight )我想尽量减less所需的内存量。 我已经尝试删除OnPause状态的图像,并在OnResume再次设置它们,但我没有运气,这是我正在尝试做的一个例子: imageView.Drawable.Callback = null; ((BitmapDrawable)imageView.Drawable).Bitmap.Recycle(); imageView.Drawable.Dispose(); imageView.SetImageDrawable(null); imageView.SetImageBitmap(null); GC.Collect(); 我不知道是否删除OnPause上的Bitmap是最好的策略,但它应该工作。 我不明白为什么ImageView没有被GC收集(因为没有外部引用) 编辑这是我如何加载图像。 即使将图像放在xml文件中也不起作用。 此外,我不在乎这个代码,我只是想处置位图。 void SetBackgroundImages(int imageId, int resId, float width, float height) { var imageView = FindViewById<ImageView>(imageId); using (var bitmap = DecodeSampledBitmapFromResource(Resources, resId, width, height)) imageView.SetImageBitmap(bitmap); } public static Bitmap DecodeSampledBitmapFromResource(Resources res, int resId, float reqWidth, float reqHeight) { var […]

FragmentStatePagerAdapter内存泄漏(与viewpager嵌套的片段)

我在我的适配器中有一个“内存泄漏”(引号将在后面解释)。 我目前使用嵌套的片段来承载一个viewpager。 我的设置如下: 1.活动(主pipe片段A的空活动) 2.片段A – 使用Fragmentstatepageradapter托pipeviewpager的片段。 每个viewpager页面主持片段B. 3.片段B – 包含imageview的片段。 除非发生configuration更改,否则一切都很好。 监控堆,每发生一次旋转,似乎就会增长100 kb。 手动GCing不释放内存。 我试过的东西: 1.用空片段replace片段B – 同样的问题发生,所以它不是造成问题的imageview。 2.删除片段A和B并旋转活动。 没有发生内存泄漏,所以它不是活动。 3.在任何方向改变之前和旋转约50次之后使用MAT来堆起来。 MAT显示了1个主要的嫌疑犯,这是我的适配器类。 它显示了7MB的观察者留下的堆(非常小的浅堆)如此: array java.util.ArrayList @ 0x42079938 24 7,000,832 .\mObservers android.database.DataSetObservable @ 0x42053508 16 7,000,848 ..\mObservable com.example.main.Adapter@ 0x4205a048 40 7,001,416 为什么我在片段中使用viewpager: 1.通过设置setretaininstance(true),我想保持与viewpager相关的适配器和其他variables的状态。 2.更改configuration后,我不重新创build适配器,而是使用旧的适配器连接到viewpager。 3.如果我不重复使用旧的适配器,而是在更改configuration后创build新的适配器,则内存泄漏消失。 4.closures活动并返回上一个活动后,内存泄漏也消失。 有任何想法吗? 将不胜感激任何帮助。 谢谢,JC

ServiceConnection在Android中泄漏

我试图在Android中使用一些服务来进行一些基本的数据库操作,但由于某种原因,我得到一个Activity泄漏了ServiceConnection错误。 我将在底部发布完整的Logcat读数。 我必须在多个活动中使用相同的服务,所以我创build了一个超类来处理所有的服务任务。 它看起来像这样: private MyInterface child; public void onCreate(Bundle savedInstanceState, MyInterface child){ super.onCreate(savedInstanceState); doBindService(); } public void onResume(){ super.onResume(); doBindService(); } protected void onPause(){ super.onPause(); doUnbindService(); } private boolean bound; private boolean binding; ServiceConnection Connection = new ServiceConnection(){ //called when the service is connected @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.d(LOGTAG, "Bound […]

Android ADT 21.0.0。 内存泄漏graphics布局

我在eclipse 4.2.1上运行ADT 21.0.0.v201210310015-519525,每次我开始处理graphics布局时,eclipse慢慢地开始无响应。 打开〜5个这样的文件后,几乎不可用,需要重新启动。 任何人都有这些问题? 我已经在eclipse中设置我的.ini增加内存和Java 1.6像在某些解决scheme中提到的,但问题仍然存在。 -Dosgi.requiredJavaVersion = 1.6 -Xms128m -Xmx1024m

view.getViewTreeObserver()。addOnGlobalLayoutListener泄漏片段

当我使用GlobalLayoutListener来查看softKeyboard是否被打开时,碎片在被销毁后不再被garbageCollected了。 我做的事: 我删除我的片段onDestroy()中的侦听器 我在onDestroy()中将侦听器设置为null 我将在onDestroy()观察到的视图设置为null 仍然泄漏片段。 有没有人有类似的问题,并知道它的修复? 我的onDestroy : @Override public void onDestroy(){ Log.d(TAG , "onDestroy"); if(Build.VERSION.SDK_INT < 16){ view.getViewTreeObserver().removeGlobalOnLayoutListener(gLayoutListener); }else{ view.getViewTreeObserver().removeOnGlobalLayoutListener(gLayoutListener); } view = null; gLayoutListener = null; super.onDestroy(); }

ByteBuffer不释放内存

在Android上,直接的ByteBuffer似乎并没有释放内存,甚至在调用System.gc()时也没有。 例如:做 Log.v("?", Long.toString(Debug.getNativeHeapAllocatedSize())); ByteBuffer buffer = allocateDirect(LARGE_NUMBER); buffer=null; System.gc(); Log.v("?", Long.toString(Debug.getNativeHeapAllocatedSize())); 在日志中给出两个数字,第二个至less比第一个数字大LARGE_NUMBER。 我如何摆脱这个泄漏? 添加: 遵循格雷戈里的build议来处理C ++端的alloc / free,然后我定义了它 JNIEXPORT jobject JNICALL Java_com_foo_bar_allocNative(JNIEnv* env, jlong size) { void* buffer = malloc(size); jobject directBuffer = env->NewDirectByteBuffer(buffer, size); jobject globalRef = env->NewGlobalRef(directBuffer); return globalRef; } JNIEXPORT void JNICALL Java_com_foo_bar_freeNative(JNIEnv* env, jobject globalRef) { void *buffer = env->GetDirectBufferAddress(globalRef); […]

“警告:不要将Android上下文类放置在静态字段中; 这是一个内存泄漏(并打破即时运行)“

在这里 , 这里和这里 提出了类似的问题,但是上下文与这个完全不同,而且这个错误给出的代码是由Android和Android Studio制造商编写的。 这是代码: public class MySingleton { private static MySingleton mInstance; private RequestQueue mRequestQueue; private ImageLoader mImageLoader; private static Context mCtx; private MySingleton(Context context) { mCtx = context; mRequestQueue = getRequestQueue(); mImageLoader = new ImageLoader(mRequestQueue, new ImageLoader.ImageCache() { private final LruCache<String, Bitmap> cache = new LruCache<String, Bitmap>(20); @Override public Bitmap getBitmap(String url) […]

Backstack上的Android碎片占用了太多的内存

问题: 我有一个Android应用程序,允许用户浏览到用户的configuration文件ViewProfileFragment 。 在ViewProfileFragment的内部,用户可以点击一个图像,将他带到StoryViewFragment各个用户的照片显示。 点击一个用户个人资料照片,可以将他们带到ViewProfileFragment另一个实例,并使用新的用户configuration文件。 如果用户重复点击用户的configuration文件,点击一个图像,将他们带到图库,然后点击另一个configuration文件碎片快速堆积在内存中导致可怕的OutOfMemoryError 。 以下是我所描述的stream程图: UserA点击Bob的个人资料。 在Bob的个人资料里UserA点击ImageA,把他带到各种用户(包括Bob's)的照片库中。 UserA点击Sue的个人资料,然后点击其中一个图像 – 处理重复等。 UserA -> ViewProfileFragment StoryViewFragment -> ViewProfileFragment StoryViewFragment -> ViewProfileFragment 正如您从典型stream程中看到的那样, StoryViewFragment和StoryViewFragment在StoryViewFragment堆积了很多实例。 相关的代码 我用下面的逻辑将它们作为碎片加载: //from MainActivity fm = getSupportFragmentManager(); ft = fm.beginTransaction(); ft.replace(R.id.activity_main_content_fragment, fragment, title); ft.addToBackStack(title); 我试过了什么 1)我特别使用FragmentTransaction replace以便在replace发生时触发onPause方法。 在onPause里面,我试图释放尽可能多的资源(比如清理ListView数据,清空variables等数据),这样当这个片段不是活动片段,并且被推到后台时,会有更多的记忆释放。 但是我释放资源的努力只是部分成功。 根据MAT,我仍然有很多被GalleryFragment和GalleryFragment使用的内存。 2)我也删除了对addToBackStack()的调用,但显然这提供了糟糕的用户体验,因为它们不能遍历(应用程序只是在用户点击后退button时closures)。 3)我用MAT来查找所有占用大量空间的对象,并且在onPause (和onResume )方法内部以各种方式处理这些对象以释放资源,但是它们的大小仍然相当大。 4)我也写了一个for循环在两个片段onPause使用以下逻辑将我的所有ImageViews为null: for (int i=shell.getHeaderViewCount(); i<shell.getCount(); i++) { […]