内存泄漏分析(二)

   上一篇说过,我的项目很特殊,就是只有一个页面,定时从服务器获取数据,并显示界面。因为业务的保密性,不好直接贴图。


看着很简单的一个界面,运行内存是这样的


最少的也是100M左右。等到跳到200多M的时候,离崩溃已经不远了。我就让程序这样运行,看着下面跳到的线。我采取了最原始的方式。屏蔽代码,只留最简单的网络访问。经过观察我发现问题


网络访问我用的是retrofit,访问完成的结果是个json字符串。


就是这样的一个变量定义与赋值,造成了短时间内的内存猛增。

再看这样一些傻傻的类。这些变量是成员变量

局部变量,存放在栈空间中,书写在方法或语句块中。语句块一结束,变量空间马上释放。所以,局部变量不能跨方法或语句块使用。

成员变量(属性):存放在堆中,书写在方法外,类中。随对象产生而产生,随对象销毁而消失。


我最初的想法是这些变量写在类里,每15s获取一次,也不用创建很多次,并且每次赋值前,我都置空了的。事实胜于雄辩,当我把这些变量全部改为局部变量以后,内存变化如下:


接下来我先加了底部的几个自定义的控件,没有太大的变化。最后加了地图。地图那块本来是有很多图标的,我把图标交给了Picasso 的框架去管理。

写法如下:附上整个MapUtils的类

public class MapUtils {
    public static final int STYPE_SHOW_MENDIAN = 0;
    public static final int STYPE_SHOW_DINGDAN = 1;
    public static final int STYPE_SHOW_QISHOU = 2;

    private static List<BitmapDescriptor> mOptionList = new ArrayList<>();
    private static List<Marker> markerList = new ArrayList<>();
    private static ArrayList<MarkerOptions> makergroup = new ArrayList<>();
    private static List<View> views = new ArrayList<>();

    /**
     * 最大最小经纬度的获取
     *
     */
    public static double[] getMaxMinLatLng(AMap aMap) {
        CameraPosition cameraPosition = aMap.getCameraPosition();
        LatLng target = cameraPosition.target;
        float zoom = cameraPosition.zoom;
        LatLngBounds latlngBounds = aMap.getProjection().getMapBounds(target, zoom);
        //东北角即地图可视范围右上角经纬度,为屏幕范围内最大
        LatLng northeast = latlngBounds.northeast;
        //西南角即地图可视范围左下角经纬度,为屏幕范围内最小
        LatLng sourthwest = latlngBounds.southwest;
        double maxLat = northeast.latitude;
        double maxLng = northeast.longitude;
        double minLat = sourthwest.latitude;
        double minLng = sourthwest.longitude;
        return new double[]{maxLat, minLat, maxLng, minLng};
    }



    /**
     * 添加Marker View
     *
     * @param context     context
     * @param startLatLng 经纬度
     * @param aMap        高德aMap
     */
    public static void addMarkerToMap(Context context, LatLng startLatLng, String pm_val, int stype, AMap aMap) {
        @SuppressLint("InflateParams")
        View view = LayoutInflater.from(context).inflate(R.layout.mymarker, null);
        TextView tv_val= view.findViewById(R.id.marker_tv_val);
        switch (stype){
            case STYPE_SHOW_MENDIAN:
                tv_val.setBackgroundResource(R.drawable.icon_mendian);
                break;
            case STYPE_SHOW_DINGDAN:
                tv_val.setBackgroundResource(R.drawable.icon_dingdan);
                break;
            case STYPE_SHOW_QISHOU:
                tv_val.setBackgroundResource(R.drawable.icon_qishou);
                break;
        }
        tv_val.setText(pm_val);
        BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromView(view);
        MarkerOptions markerOptions = new MarkerOptions().icon(bitmapDescriptor);
        if (bitmapDescriptor != null) {
            if (mOptionList != null) {
                mOptionList.add(bitmapDescriptor);
            }
        }
        if (view != null) {
            if (views != null) {
                views.add(view);
            }
        }
        markerOptions.position(startLatLng);
        Marker growMarker = aMap.addMarker(markerOptions);
        if (growMarker != null) {
            if (markerList != null) {
                markerList.add(growMarker);
            }
        }
    }


    public static void addMarkerGroups(Context context, List<LatLng> addressgroups, int resources, final AMap aMap) {
        for (int i = 0; i < addressgroups.size(); i++) {
            final MarkerOptions options = new MarkerOptions();
            options.position(addressgroups.get(i));
            Picasso.with(context).load(resources)
                   // .placeholder(R.drawable.location)
                 //   .error(R.drawable.location)
                    .into(new Target() {
                        @Override
                        public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                            options.icon(BitmapDescriptorFactory.fromBitmap(bitmap));
                            aMap.addMarker(options);
                        }

                        @Override
                        public void onBitmapFailed(Drawable errorDrawable) {
                            options.icon(BitmapDescriptorFactory.fromBitmap(((BitmapDrawable) errorDrawable).getBitmap()));
                            aMap.addMarker(options);
                        }

                        @Override
                        public void onPrepareLoad(Drawable placeHolderDrawable) {
                        }
                    });

            options.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory
                    .decodeResource(context.getResources(), resources)));
            options.draggable(true);
            makergroup.add(options);
        }
        aMap.addMarkers(makergroup, true);
    }


    public static void clearIconMarkers() {
        if (makergroup != null && makergroup.size() > 0) {
            makergroup.clear();
        }
        if (mOptionList.size() > 0) {
            try {
                for (int i = 0; i < mOptionList.size(); i++) {
                    if (null != mOptionList.get(i)) {
                        mOptionList.get(i).recycle();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (markerList != null && markerList.size() > 0) {
            markerList.clear();
        }
        if (views != null && views.size() > 0) {
            for (View view : views) {
                view = null;
            }
            views.clear();
        }
    }


}

如此修改,经过我的长时间的测试:



现在的大致运行情况就是这样。虽然没有再因内存而崩溃,但是我既然开始做内存分析,就将深入地了解一下,我接下来将用mat工具去分析内存情况。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值