首页 文章 精选 留言 我的

精选列表

搜索[优化],共10000篇文章
优秀的个人博客,低调大师

Android内存优化8 内存检测工具2 LeakCanary——直白的展现Android中的内存泄露

之前碰到的OOM问题,终于很直白的呈现在我的眼前:我尝试了MAT,但是发现不怎么会用。直到今天终于发现了这个新工具: 当我们的App中存在内存泄露时会在通知栏弹出通知: 当点击该通知时,会跳转到具体的页面,展示出Leak的引用路径,如下图所示: LeakCanary 可以用更加直白的方式将内存泄露展现在我们的面前。 以下是我找到的学习资料,写的非常棒: 1、LeakCanary: 让内存泄露无所遁形 2、LeakCanary 中文使用说明 AndroidStudio(官方)上使用LeakCanary 请移步:https://github.com/square/leakcanary Eclipse上使用LeakCanary 请移步我的:https://github.com/SOFTPOWER1991/LeakcanarySample-Eclipse Androidstudio(自己弄的)上使用LeakCanary也可以看这个: leakcanarySample_androidStudio 工程包括: LeakCanary库代码 LeakCanaryDemo示例代码 使用步骤: 将LeakCanary import 入自己的工程 添加依赖: compile project(':leakcanary') 在Application中进行配置 public class ExampleApplication extends Application { ...... //在自己的Application中添加如下代码 public static RefWatcher getRefWatcher(Context context) { ExampleApplication application = (ExampleApplication) context .getApplicationContext(); return application.refWatcher; } //在自己的Application中添加如下代码 private RefWatcher refWatcher; @Override public void onCreate() { super.onCreate(); ...... //在自己的Application中添加如下代码 refWatcher = LeakCanary.install(this); ...... } ..... } 在Activity中进行配置 public class MainActivity extends AppCompatActivity { ...... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //在自己的应用初始Activity中加入如下两行代码 RefWatcher refWatcher = ExampleApplication.getRefWatcher(this); refWatcher.watch(this); textView = (TextView) findViewById(R.id.tv); textView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startAsyncTask(); } }); } private void async() { startAsyncTask(); } private void startAsyncTask() { // This async task is an anonymous class and therefore has a hidden reference to the outer // class MainActivity. If the activity gets destroyed before the task finishes (e.g. rotation), // the activity instance will leak. new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... params) { // Do some slow work in background SystemClock.sleep(20000); return null; } }.execute(); } } 在AndroidMainfest.xml 中进行配置,添加如下代码 <service android:name="com.squareup.leakcanary.internal.HeapAnalyzerService" android:enabled="false" android:process=":leakcanary" /> <service android:name="com.squareup.leakcanary.DisplayLeakService" android:enabled="false" /> <activity android:name="com.squareup.leakcanary.internal.DisplayLeakActivity" android:enabled="false" android:icon="@drawable/__leak_canary_icon" android:label="@string/__leak_canary_display_activity_label" android:taskAffinity="com.squareup.leakcanary" android:theme="@style/__LeakCanary.Base" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> 5、测试结果 a、Toast显示(大概10秒左右显示) b、通知显示 c、桌面自动添加的图表 d、内存泄露列表 e、内存泄露详细 LogCat可以看到日志日下(hprof文件可以用MAT打开进行分析): [html] view plain copy 01-0411:49:41.81512967-13004/com.micky.leakcanarysamplesI/dalvikvm:hprof:dumpingheapstringsto"/storage/emulated/0/Download/leakcanary/suspected_leak_heapdump.hprof". 01-0411:49:42.02012967-13004/com.micky.leakcanarysamplesI/dalvikvm:hprof:heapdumpcompleted(28850KB) 查看自动生成的AndroidManifest文件,LeakCanarySamples/app/build/intermediates/manifests/full/debug/AndroidManifest.xml [html] view plain copy <?xmlversion="1.0"encoding="utf-8"?> <manifestxmlns:android="http://schemas.android.com/apk/res/android" package="com.micky.leakcanarysamples" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="23"/> <!--Tostoretheheapdumpsandleakanalysisresults.--> <uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <android:uses-permissionandroid:name="android.permission.READ_EXTERNAL_STORAGE"/> <application android:name="com.micky.leakcanarysamples.BaseApplication" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name="com.micky.leakcanarysamples.MainActivity" android:label="@string/app_name" android:theme="@style/AppTheme.NoActionBar"> <intent-filter> <actionandroid:name="android.intent.action.MAIN"/> <categoryandroid:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activityandroid:name="com.micky.leakcanarysamples.TestActivity"/> <service android:name="com.squareup.leakcanary.internal.HeapAnalyzerService" android:enabled="false" android:process=":leakcanary"/> <service android:name="com.squareup.leakcanary.DisplayLeakService" android:enabled="false"/> <activity android:name="com.squareup.leakcanary.internal.DisplayLeakActivity" android:enabled="false" android:icon="@drawable/__leak_canary_icon" android:label="@string/__leak_canary_display_activity_label" android:taskAffinity="com.squareup.leakcanary" android:theme="@style/__LeakCanary.Base"> <intent-filter> <actionandroid:name="android.intent.action.MAIN"/> <categoryandroid:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> </manifest> 如上所示LeakCanary给我们自动添加了两个Service和一个Activity,并添加了对SD卡的读写权限 It 's so simple. 注: 1、如果在Release模式下请使用RefWatcher.DISABLED 2、在Activity或Fragment 的 Destroy方法中添加检测(很好理解,就是判断一个Activity或Fragment想要被销毁的时候,是否还有其他对象持有其引用导致Activity或Fragment不能被回收,从而导致内存泄露) 本文转自 一点点征服 博客园博客,原文链接: http://www.cnblogs.com/ldq2016/p/8472721.html ,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android内存优化14 内存泄漏常见情况5 特殊对象造成的内存泄漏 WebView内存泄漏

WebView造成内存泄露 关于WebView的内存泄露,因为WebView在加载网页后会长期占用内存而不能被释放,因此我们在Activity销毁后要调用它的destory()方法来销毁它以释放内存。 另外在查阅WebView内存泄露相关资料时看到这种情况: Webview下面的Callback持有Activity引用,造成Webview内存无法释放,即使是调用了Webview.destory()等方法都无法解决问题(Android5.1之后)。 最终的解决方案是:在销毁WebView之前需要先将WebView从父容器中移除,然后在销毁WebView。详细分析过程请参考这篇文章:WebView内存泄漏解决方法。 @Override protected void onDestroy() { super.onDestroy(); // 先从父控件中移除WebView mWebViewContainer.removeView(mWebView); mWebView.stopLoading(); mWebView.getSettings().setJavaScriptEnabled(false); mWebView.clearHistory(); mWebView.removeAllViews(); mWebView.destroy(); } 前言:在项目的开发过程中,由于对内存要求较高,最近对应用的内存分析比较在意,前段时间监控图片内存,对Bitmap造成的内存泄漏进行了分析,并解决了问题。但是在图片内存泄漏之后,发现在访问网页的时候,webview竟然也会有内存泄漏,虽然内存占用很小,但是用户多次访问还是存在隐患。 于是,开始对webview进行内存分析,发现webview下面的callback持有activity引用,造成webview内存无法释放,在网上也找了很多方法,但是webview.destory()等方法大都无法解决问题。 最后看到一篇文章,才算明了出现这个bug的原因,按照作者的做法,确实解决了问题,安卓5.1和6.0系统都不存在内存泄漏问题。 文章附下:销毁webview的方式 从 mWebView.removeAllViews(); /**、 * 这里内存泄漏了,因为它的父容器在退出前没有被销毁,所以就会持有引用,内存泄漏 * */ // mWebView.destroy(); 改为 在Android5.1 系统上,在项目中遇到一个WebView引起的问题,每打开一个带webview的界面,退出后,这个activity都不会被释放,activity的实例会被持有,由于我们项目中经常会用到浏览web页面的地方,可能引起内存积压,导致内存溢出的现象,所以这个问题还是比较严重的。 问题分析 使用Android Studio的内存monitor,得到了以下的内存分析,我打开了三个BookDetailActivity界面(都有webview),检查结果显示有3个activity泄漏,如下图所示: 这个问题还是比较严重的,那么进一步看详细的信息,找出到底是哪里引起的内存泄漏,详情的reference tree如下图所示: 从上图中可以看出,在第1层中的 TBReaderApplication 中的 mComponentCallbacks 成员变量,它是一个array list,它里面会持有住activity,引导关系是 mComponentCallbacks->AwContents->BaseWebView->BookDetailActivity, 代码在 Application 类里面,代码如下所示: public void registerComponentCallbacks(ComponentCallbacks callback) { synchronized (mComponentCallbacks) { mComponentCallbacks.add(callback); } } public void unregisterComponentCallbacks(ComponentCallbacks callback) { synchronized (mComponentCallbacks) { mComponentCallbacks.remove(callback); } } 上面两个方法,会在 Context 基类中被调用,代码如下: /** * Add a new {@link ComponentCallbacks} to the base application of the * Context, which will be called at the same times as the ComponentCallbacks * methods of activities and other components are called. Note that you * <em>must</em> be sure to use {@link #unregisterComponentCallbacks} when * appropriate in the future; this will not be removed for you. * * @param callback The interface to call. This can be either a * {@link ComponentCallbacks} or {@link ComponentCallbacks2} interface. */ public void registerComponentCallbacks(ComponentCallbacks callback) { getApplicationContext().registerComponentCallbacks(callback); } /** * Remove a {@link ComponentCallbacks} object that was previously registered * with {@link #registerComponentCallbacks(ComponentCallbacks)}. */ public void unregisterComponentCallbacks(ComponentCallbacks callback) { getApplicationContext().unregisterComponentCallbacks(callback); } 从第二张图我们已经知道,是webview引起的内存泄漏,而且能看到是在 org.chromium.android_webview.AwContents 类中,难道是这个类注册了component callbacks,但是未反注册?一般按系统设计,都会反注册的,最有可能的原因就是某些情况下导致不能正常反注册,不多说,read the fucking source。基于这个思路,我把chromium的源码下载下来,代码在这里 chromium_org(https://android.googlesource.com/platform/external/chromium_org/?spm=5176.100239.blogcont61612.7.j9EPtE) 然后找到 org.chromium.android_webview.AwContents 类,看看这两个方法 onAttachedToWindow 和 onDetachedFromWindow: @Override public void onAttachedToWindow() { if (isDestroyed()) return; if (mIsAttachedToWindow) { Log.w(TAG, "onAttachedToWindow called when already attached. Ignoring"); return; } mIsAttachedToWindow = true; mContentViewCore.onAttachedToWindow(); nativeOnAttachedToWindow(mNativeAwContents, mContainerView.getWidth(), mContainerView.getHeight()); updateHardwareAcceleratedFeaturesToggle(); if (mComponentCallbacks != null) return; mComponentCallbacks = new AwComponentCallbacks(); mContext.registerComponentCallbacks(mComponentCallbacks); } @Override public void onDetachedFromWindow() { if (isDestroyed()) return; if (!mIsAttachedToWindow) { Log.w(TAG, "onDetachedFromWindow called when already detached. Ignoring"); return; } mIsAttachedToWindow = false; hideAutofillPopup(); nativeOnDetachedFromWindow(mNativeAwContents); mContentViewCore.onDetachedFromWindow(); updateHardwareAcceleratedFeaturesToggle(); if (mComponentCallbacks != null) { mContext.unregisterComponentCallbacks(mComponentCallbacks); mComponentCallbacks = null; } mScrollAccessibilityHelper.removePostedCallbacks(); } 系统会在attach处detach进行注册和反注册component callback,注意到 onDetachedFromWindow() 方法的第一行,if (isDestroyed()) return;, 如果 isDestroyed() 返回 true 的话,那么后续的逻辑就不能正常走到,所以就不会执行unregister的操作,通过看代码,可以得到,调用主动调用 destroy()方法,会导致 isDestroyed() 返回 true。 /** * Destroys this object and deletes its native counterpart. */ public void destroy() { if (isDestroyed()) return; // If we are attached, we have to call native detach to clean up // hardware resources. if (mIsAttachedToWindow) { nativeOnDetachedFromWindow(mNativeAwContents); } mIsDestroyed = true; new Handler().post(new Runnable() { @Override public void run() { destroyNatives(); } }); } 一般情况下,我们的activity退出的时候,都会主动调用 WebView.destroy() 方法,经过分析,destroy()的执行时间在onDetachedFromWindow之前,所以就会导致不能正常进行unregister()。 解决方案 找到了原因后,解决方案也比较简单,核心思路就是让onDetachedFromWindow先走,那么在主动调用之前destroy(),把webview从它的parent上面移除掉。 ViewParent parent = mWebView.getParent(); if (parent != null) { ((ViewGroup) parent).removeView(mWebView); } mWebView.destroy(); 完整的代码如下: public void destroy() { if (mWebView != null) { // 如果先调用destroy()方法,则会命中if (isDestroyed()) return;这一行代码,需要先onDetachedFromWindow(),再 // destory() ViewParent parent = mWebView.getParent(); if (parent != null) { ((ViewGroup) parent).removeView(mWebView); } mWebView.stopLoading(); // 退出时调用此方法,移除绑定的服务,否则某些特定系统会报错 mWebView.getSettings().setJavaScriptEnabled(false); mWebView.clearHistory(); mWebView.clearView(); mWebView.removeAllViews(); try { mWebView.destroy(); } catch (Throwable ex) { } } } Android 5.1之前的代码 对比了5.1之前的代码,它是不会存在这样的问题的,以下是kitkat的代码,它少了一行 if (isDestroyed()) return;,有点不明白,为什么google在高版本把这一行代码加上。 /** * @see android.view.View#onDetachedFromWindow() */ public void onDetachedFromWindow() { mIsAttachedToWindow = false; hideAutofillPopup(); if (mNativeAwContents != 0) { nativeOnDetachedFromWindow(mNativeAwContents); } mContentViewCore.onDetachedFromWindow(); if (mComponentCallbacks != null) { mContainerView.getContext().unregisterComponentCallbacks(mComponentCallbacks); mComponentCallbacks = null; } if (mPendingDetachCleanupReferences != null) { for (int i = 0; i < mPendingDetachCleanupReferences.size(); ++i) { mPendingDetachCleanupReferences.get(i).cleanupNow(); } mPendingDetachCleanupReferences = null; } } 结束 在开发过程中,还发现一个支付宝SDK的内存问题,也是因为这个原因,具体的类是 com.alipay.sdk.app.H5PayActivity,我们没办法,也想了一个不是办法的办法,在每个activity destroy时,去主动把 H5PayActivity 中的webview从它的parent中移除,但这个问题限制太多,不是特别好,但的确也能解决问题,方案如下: /** * 解决支付宝的 com.alipay.sdk.app.H5PayActivity 类引起的内存泄漏。 * * <p> * 说明:<br> * 这个方法是通过监听H5PayActivity生命周期,获得实例后,通过反射将webview拿出来,从 * 它的parent中移除。如果后续支付宝SDK官方修复了该问题,则我们不需要再做什么了,不管怎么 * 说,这个方案都是非常恶心的解决方案,非常不推荐。同时,如果更新了支付宝SDK后,那么内部被混淆 * 的字段名可能更改,所以该方案也无效了。 * </p> * * @param activity */ public static void resolveMemoryLeak(Activity activity) { if (activity == null) { return; } String className = activity.getClass().getCanonicalName(); if (TextUtils.equals(className, "com.alipay.sdk.app.H5PayActivity")) { Object object = Reflect.on(activity).get("a"); if (DEBUG) { LogUtils.e(TAG, "AlipayMemoryLeak.resolveMemoryLeak activity = " + className + ", field = " + object); } if (object instanceof WebView) { WebView webView = (WebView) object; ViewParent parent = webView.getParent(); if (parent instanceof ViewGroup) { ((ViewGroup) parent).removeView(webView); } } } } 本文转自 一点点征服 博客园博客,原文链接:http://www.cnblogs.com/ldq2016/p/8474172.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

CVPR2017精彩论文解读:效果更显著的模型压缩算法和泛化优化算法

雷锋网(公众号:雷锋网) AI科技评论按:虽然CVPR 2017已经落下帷幕,但对精彩论文的解读还在继续。下文是优必选悉尼AI研究院对其入选CVPR 2017的两篇论文《基于低秩稀疏分解的深度模型压缩算法》和《利用奇异值界定提升深度神经网络训练效果和识别精度》进行的解读,除此之外他们还对会上Workshop竞赛的进行了相关介绍。 基于低秩稀疏分解的深度模型压缩算法——On Compressing Deep Models by Low Rank and Sparse Decomposition 深度学习极大地促进了人工智能的发展,同时也带来了新的挑战:深度神经网络往往需要消耗巨大的存储和计算资源。这极大地限制了深度学习在计算能力有限的平台(如移动手机)上的应用。深度模型压缩旨在挖掘并去除深度神经网络中参数和特征的冗余信息,从而达到减

优秀的个人博客,低调大师

Kubernetes1.7正式发布,优化了可扩展性,安全增强和网络通信策略

Kubernetes 1.7已经发布本文Ghostcloud将为大家深度分析新版本的可扩展性和安全性以及一系列新特性。 Kubernetes 1.7包括了4个稳定特性7个公测版和19个内测版有来自谷歌、CoreOS、Mirantis、Red Hat、微软等公司的370余人参与了这个新版本的发布。 一般情况下内测版本中的特性不会被默认开启它们不会被官方社区认为是“生产就绪”了的产品功能但用户可以选择使用它们。公测版的功能则是经过大量用户测试的默认开启在后面的版本中它们可能会有改变。 4个稳定的特性意味着这部分产品内容已经被证明准备就绪禁得住考验并将在许多后续版本中沿用 1、用于限制容器网络流量的网络策略API2、用于负载平衡器的源IP处理3、StorageOS卷插件4、云存储指标 改进的可扩展性旨在扩大Kubernetes的范围和功能不会使核

优秀的个人博客,低调大师

技术日报|Karpathy 的 Claude 优化配置单日揽星 9263 登顶,hermes-agent 总量突破 8.4 万

🌟 TrendForge 每日精选 - 发现最具潜力的开源项目 📊 今日共收录 13 个热门项目 🌐 智能中文翻译版 - 项目描述已自动翻译,便于理解 🏆 今日最热项目 Top 10 🥇 forrestchang/andrej-karpathy-skills 项目简介: 一个独立的CLAUDE.md文件,用于改进Claude代码行为,源自Andrej Karpathy对大型语言模型编码常见... 今日新增: 9263 * 总星数: 33473 * 语言: 未指定 https://github.com/forrestchang/andrej-karpathy-skills 🥈 NousResearch/hermes-agent 项目简介: 与你共同成长的智能体 今日新增: 8301 * 总星数: 84150 * 语言: Python 项目截图: NousResearch/hermes-agent https://github.com/NousResearch/hermes-agent 🥉 thedotmack/claude-mem 项目简介: Claude Code插件可自动记录编码会话中Claude的全部操作,通过AI技术进行压缩处理,并将相关上下文智能注入后... 今日新增: 2997 * 总星数: 55700 * 语言: TypeScript 项目截图: thedotmack/claude-mem https://github.com/thedotmack/claude-mem 4. shanraisshan/claude-code-best-practice 项目简介: 熟能生巧 今日新增: 2583 * 总星数: 43713 * 语言: HTML 项目截图: shanraisshan/claude-code-best-practice https://github.com/shanraisshan/claude-code-best-practice 5. obra/superpowers 项目简介: Claude Code 超级能力:核心技能库 今日新增: 1919 * 总星数: 152227 * 语言: Shell https://github.com/obra/superpowers 6. microsoft/markitdown 项目简介: 用于将文件和办公文档转换为Markdown的Python工具。 今日新增: 1675 * 总星数: 108401 * 语言: Python https://github.com/microsoft/markitdown 7. jamiepine/voicebox 项目简介: 开源语音合成工作室 今日新增: 1162 * 总星数: 17299 * 语言: TypeScript 项目截图: jamiepine/voicebox https://github.com/jamiepine/voicebox 8. virattt/ai-hedge-fund 项目简介: 人工智能对冲基金团队 今日新增: 1007 * 总星数: 54101 * 语言: Python 项目截图: virattt/ai-hedge-fund https://github.com/virattt/ai-hedge-fund 9. shiyu-coder/Kronos 项目简介: Kronos:金融市场语言基础模型 今日新增: 963 * 总星数: 17780 * 语言: Python 项目截图: shiyu-coder/Kronos https://github.com/shiyu-coder/Kronos 10. anthropics/claude-cookbooks 项目简介: 一套展示Claude有趣且高效使用方法的笔记本/方案合集。 今日新增: 931 * 总星数: 40227 * 语言: Jupyter Notebook https://github.com/anthropics/claude-cookbooks 📈 今日趋势分析 最活跃语言: Python(4个)、TypeScript(3个)、Shell(2个) 今日总获星: 32,362 颗星 平均获星: 2489 颗星/项目 今日之星: forrestchang/andrej-karpathy-skills (9263) 📊 数据总览 指标 数值 收录项目 13 个 编程语言 0 种 今日新增 32,362 颗星 报告日期 2026年04月14日 统计周期 日报 TrendForge 致力于追踪全球开源项目动态,每日为开发者精选最具价值的 GitHub 项目。 数据来源: https://trendforge.devlive.top/ 数据说明: 基于 GitHub 官方 API 数据统计,每日更新 翻译声明: 项目描述采用 AI 智能翻译,如有疏漏请以原文为准 报告生成于: 2026年04月15日 #GitHub #开源项目 #技术趋势 #程序员 #软件开发

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册