Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/220.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/kubernetes/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 查看寻呼机内存分析器_Android_Memory Leaks_Garbage Collection - Fatal编程技术网

Android 查看寻呼机内存分析器

Android 查看寻呼机内存分析器,android,memory-leaks,garbage-collection,Android,Memory Leaks,Garbage Collection,我编写了一个图书阅读器应用程序,它使用带有FragmentStatePagerAdapter的视图寻呼机。它没有明显的运行时错误。但是,当页面被刷洗时,内存的使用会不断增加。所以我测试了一个简单版本的设置,并在Nexus7上进行了测试。用户需要在几次滑动和几次旋转之间交替进行。在多次执行这些操作之后,从日志中可以看到堆使用量不断增加。我认为这暗示着内存泄漏。然而,我无法找出它的原因。附件是代码、GC日志和MAT的两名泄漏嫌疑人。如有任何有用的见解,将不胜感激。谢谢 MainActivity.ja

我编写了一个图书阅读器应用程序,它使用带有FragmentStatePagerAdapter的视图寻呼机。它没有明显的运行时错误。但是,当页面被刷洗时,内存的使用会不断增加。所以我测试了一个简单版本的设置,并在Nexus7上进行了测试。用户需要在几次滑动和几次旋转之间交替进行。在多次执行这些操作之后,从日志中可以看到堆使用量不断增加。我认为这暗示着内存泄漏。然而,我无法找出它的原因。附件是代码、GC日志和MAT的两名泄漏嫌疑人。如有任何有用的见解,将不胜感激。谢谢

MainActivity.java:

package com.example.leakypager;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;

public class MainActivity extends FragmentActivity {

    public static final String TAG = "MainActivity";
    public static final String EXTRA_argument = "pageNumber";
    private static final int viewPagerId = 1;
    private static final int totalPages = 10;

    private int mPageNumber;
    private ViewPager mViewPager; 
    private int mTotalPages;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Set a default value to page 1
        mPageNumber = getIntent().getIntExtra(EXTRA_argument, 1);

        Log.i(TAG, "Called onCreate() on page number " + mPageNumber);

        mViewPager = new ViewPager(this);
        mViewPager.setId(viewPagerId);
        setContentView(mViewPager);

        mTotalPages = totalPages;

        FragmentManager fragmentManager;
        fragmentManager = getSupportFragmentManager();      

        mViewPager.setAdapter(new FragmentStatePagerAdapter(fragmentManager) {
            @Override
            public Fragment getItem(int pos) {
                // The page number is one greater than the pager index.
                Fragment pageFragment;
                pageFragment = PageFragment.newInstance(pos+1);                 
                return pageFragment;
            }

            @Override
            public int getCount() {
                return mTotalPages;  
            }

            @Override
            public int getItemPosition(Object item) {
                return POSITION_NONE;
            }
        });

        if (mPageNumber >= 1 && mPageNumber <= mTotalPages) {
            // The pager item index is one less than the page number.
            mViewPager.setCurrentItem(mPageNumber-1); 
        }
    }
}
布局文件在LinearLayout中仅包含一个textview和一个edit文本。(除非另有要求,否则不得在此复制)

带有GC筛选器的日志显示以下结果:

12-06 00:07:03.205: D/dalvikvm(23276): GC_FOR_ALLOC freed 232K, 4% free 7758K/8052K, paused 16ms, total 18ms
12-06 00:07:10.095: D/dalvikvm(23276): GC_FOR_ALLOC freed 272K, 5% free 7989K/8324K, paused 19ms, total 19ms
12-06 00:07:20.945: D/dalvikvm(23276): GC_FOR_ALLOC freed 460K, 7% free 8043K/8564K, paused 21ms, total 22ms
12-06 00:07:23.805: D/dalvikvm(23276): GC_FOR_ALLOC freed 511K, 7% free 8043K/8616K, paused 17ms, total 17ms
12-06 00:07:42.535: D/dalvikvm(23276): GC_FOR_ALLOC freed 421K, 6% free 8134K/8616K, paused 18ms, total 21ms
12-06 00:08:03.925: D/dalvikvm(23276): GC_FOR_ALLOC freed 537K, 7% free 8109K/8708K, paused 20ms, total 20ms
12-06 00:08:11.665: D/dalvikvm(23276): GC_FOR_ALLOC freed 537K, 8% free 8083K/8708K, paused 27ms, total 30ms
12-06 00:08:15.265: D/dalvikvm(23276): GC_FOR_ALLOC freed 456K, 7% free 8138K/8708K, paused 18ms, total 18ms
12-06 00:08:20.015: D/dalvikvm(23276): GC_FOR_ALLOC freed 313K, 5% free 8315K/8708K, paused 25ms, total 26ms
12-06 00:08:24.685: D/dalvikvm(23276): GC_FOR_ALLOC freed 448K, 6% free 8378K/8888K, paused 18ms, total 19ms
12-06 00:08:27.955: D/dalvikvm(23276): GC_FOR_ALLOC freed 330K, 5% free 8560K/8952K, paused 28ms, total 28ms
12-06 00:08:36.055: D/dalvikvm(23276): GC_FOR_ALLOC freed 449K, 6% free 8625K/9136K, paused 37ms, total 37ms
12-06 00:08:42.015: D/dalvikvm(23276): GC_FOR_ALLOC freed 438K, 6% free 8699K/9200K, paused 60ms, total 63ms
12-06 00:08:45.775: D/dalvikvm(23276): GC_FOR_ALLOC freed 454K, 6% free 8760K/9276K, paused 27ms, total 30ms
12-06 00:08:51.185: D/dalvikvm(23276): GC_FOR_ALLOC freed 491K, 6% free 8771K/9328K, paused 36ms, total 36ms
12-06 00:08:57.845: D/dalvikvm(23276): GC_FOR_ALLOC freed 382K, 5% free 8866K/9328K, paused 28ms, total 30ms
12-06 00:09:03.885: D/dalvikvm(23276): GC_FOR_ALLOC freed 491K, 6% free 8887K/9440K, paused 26ms, total 27ms
12-06 00:09:06.905: D/dalvikvm(23276): GC_FOR_ALLOC freed 442K, 6% free 8955K/9460K, paused 26ms, total 27ms
12-06 00:09:11.215: D/dalvikvm(23276): GC_FOR_ALLOC freed 408K, 5% free 9058K/9528K, paused 23ms, total 25ms
12-06 00:09:19.355: D/dalvikvm(23276): GC_FOR_ALLOC freed 445K, 6% free 9130K/9640K, paused 47ms, total 47ms
12-06 00:09:24.965: D/dalvikvm(23276): GC_FOR_ALLOC freed 479K, 6% free 9208K/9748K, paused 29ms, total 30ms
12-06 00:09:30.735: D/dalvikvm(23276): GC_FOR_ALLOC freed 456K, 6% free 9330K/9848K, paused 35ms, total 36ms
12-06 00:09:39.765: D/dalvikvm(23276): GC_FOR_ALLOC freed 473K, 6% free 9477K/10012K, paused 37ms, total 37ms
12-06 00:09:54.795: D/dalvikvm(23276): GC_FOR_ALLOC freed 344K, 4% free 9803K/10208K, paused 36ms, total 36ms
12-06 00:10:05.605: D/dalvikvm(23276): GC_FOR_ALLOC freed 478K, 6% free 10104K/10644K, paused 28ms, total 28ms
12-06 00:10:17.165: D/dalvikvm(23276): GC_FOR_ALLOC freed 499K, 6% free 10483K/11044K, paused 40ms, total 41ms
12-06 00:10:28.855: D/dalvikvm(23276): GC_FOR_ALLOC freed 679K, 7% free 10811K/11552K, paused 44ms, total 46ms
12-06 00:10:43.815: D/dalvikvm(23276): GC_FOR_ALLOC freed 873K, 8% free 11054K/11988K, paused 47ms, total 47ms
12-06 00:11:02.155: D/dalvikvm(23276): GC_FOR_ALLOC freed 891K, 8% free 11360K/12312K, paused 41ms, total 41ms
12-06 00:11:22.725: D/dalvikvm(23276): GC_FOR_ALLOC freed 807K, 7% free 11852K/12720K, paused 58ms, total 58ms
12-06 00:11:46.165: D/dalvikvm(23276): GC_FOR_ALLOC freed 932K, 8% free 12382K/13376K, paused 45ms, total 45ms
以下是MAT报告的两个有趣的泄漏嫌疑人:

Suspect 1. 
49 instances of "android.support.v4.app.Fragment$SavedState", 
loaded by "dalvik.system.PathClassLoader @ 0x420ebce8" occupy 
1,892,544 (16.76%) bytes. These instances are referenced from 
one instance of "java.lang.Object[]", loaded by "<system class loader>"

Keywords
java.lang.Object[]
android.support.v4.app.Fragment$SavedState
dalvik.system.PathClassLoader @ 0x420ebce8


Suspect 2.
19 instances of "com.example.leakypager.MainActivity", loaded by
"dalvik.system.PathClassLoader @ 0x420ebce8" occupy 1,419,320 (12.57%) bytes.
Biggest instances:
com.example.leakypager.MainActivity @ 0x422adfa0 - 246,896 (2.19%) bytes.
com.example.leakypager.MainActivity @ 0x4238a430 - 237,880 (2.11%) bytes.
com.example.leakypager.MainActivity @ 0x420edc60 - 160,600 (1.42%) bytes.

Keywords
dalvik.system.PathClassLoader @ 0x420ebce8
com.example.leakypager.MainActivity
实时活动之间的连接通过每个TextView(EditText是TextView)的SavedState实现,当视图发生更改时,系统会自动保存该状态。(Reference:)作为其工作的一部分,FragmentStatePagerAdapter正在引用此不幸的SavedState。与侦听器不同,当活动被销毁时,我无法从ViewPager中释放FragmentStatePagerAdapter


我注意到,这个问题不仅发生在EditText上,而且也发生在支持更改其文本格式/颜色等的TextView上。不知何故,由于TextView无法释放其McContext,我目前的解决办法是通过调用mNoteView.setSaveEnabled(false)显式阻止其保存状态;创建视图时。它不会伤害我的实际应用程序,因为我已经保存、加载/重新加载EditText的数据,只要片段恢复活动状态。然而,安卓开发者的文档似乎并不鼓励这种四处走动。也许有更好的办法。欢迎任何新的见解或专家建议

我不确定发生了什么,但我将开始在答案中加入想法,希望你能找到问题所在(比评论容易得多)

1) 尝试切换到FragmentPagerAdapter(工作方式不同)。我认为这不会有多大改变

2) 通过制作更多的最终材料来改进您的片段…例如:

final View v = inflater.inflate(R.layout.fragment_page, parent, false);
mDataView和mNoteView都是字段,它们可以是本地字段吗

尝试制作:

final TextView dataView = (TextView) v.findViewById(R.id.fragmentPage_data_id);
final EditText noteView = (EditText) v.findViewById(R.id.fragmentPage_note_id);
final
将使它们在匿名类中可用

我对此有点怀疑(在每个片段和onCreateView中:

getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
我希望在我的活动中有一个方法,片段可以调用并让活动处理这个方法(也可以是一个逻辑位置的一行代码,活动,它可以控制窗口)

此外,如果您仅在此处更改DataView和EditView,并且可以将它们设置为最终版本,则也可以修复以下行:

    dataView.setText(mData);
    noteView.setText(mNote);       
最后,我个人要改变的是你的活动

我将完全为片段适配器创建一个内部类,而不是使用匿名适配器

创建一个字段以保存它:

ViewPagerAdapter mViewPagerAdapter;

(这将是你的内心世界)

私有类ViewPagerAdapter扩展了FragmentStatePagerAdapter{

然后稍后在onCreate中实例化它:

mPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mPagerAdapter);
另外,删除FragmentManager的实例,因为您似乎不再使用它,请保存内存;)

这还可以让您执行以下操作:
mPagerAdapter.notifyDataSetChanged();
,以备不时之需


因此,如果您看到任何更改,请尝试告诉我。

为什么要…@Override public int getItemPosition(Object item){return POSITION_NONE;}这是非常低效的。在最初的应用程序中,我每次都需要刷新位置,因为当用户从菜单中选择某些选项时,所有页面上都有其他功能,如图形、屏幕布局等。这些功能不包括在这个简单的代码中,因为我想重点测试内存我使用了viewpager.Understand。我仍然没有在这里看到任何奇怪的东西…为了测试,您是否尝试过暂时切换到FragmentPagerAdapter而不是状态版本?我没有想到!我会尝试。但我确实关闭了@Override getItemPosition(Object item){return POSITION_NONE;}并再次测试。同样的现象。我怀疑有些活动没有GCed,因为有些保存的状态没有被处理。但是,当我在FragmentStatePagerAdapter中跟踪mSavedState数组的值时,它似乎从未超过10(这是预期的,因为只有10页)。谢谢。我能够采纳一些建议,但不是全部,因为原始应用程序需要以这种方式完成某些事情。在检查MAT中GC根的路径后,发现SavedState有一个指向捆绑包的指针,该捆绑包(经过许多链接后)引导到一个EditText,它指向一个活动。在我删除EditText后,内存问题消失了。老实说,这对我来说还没有意义。但我会继续探索,直到找到更满意的答案。当我认为泄漏是由EditText引起的时,我可能被误导了。仍然没有找到解释。但是威尔继续研究它。非常感谢,Martin!经过更多的调查,我认为问题确实与EditText有关。一旦我更换它,就不会再有泄漏。下面的讨论似乎与我的问题密切相关。甚至MAT中显示的GC根路径也非常相似:很高兴知道您找到了罪魁祸首!:)
    dataView.setText(mData);
    noteView.setText(mNote);       
mPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mPagerAdapter);