需要一款检测我手机内存频率不一致和卖家所说的内存频率不一致是否一致的软件

教程中心相关分类
本类热门阅览
常用装机软件
如何解决系统属性显示的可用内存和安装的内存不一致?
作者:华彩软件站&&来源:华彩软件站&&发布时间: 06:51:38
如何解决系统属性显示的可用内存和安装的内存不一致?
收集者:小路&& &发布人:小路
问题描述:
笔记本随机的Windows 7系统,安装了2G的内存,但是在计算机属性显示安装2.00GB可用为1.00GB,如何解决。如图:
解决方案:
1、WIN+R打开运行输入Msconfig,选择引导--高级选项。如下图:
2、在引导高级选项里面取消最大内存前面的勾选,点击确定。重启电脑问题解决 。
如何解决系统属性显示的可用内存和安装的内存不一致?由华彩软件站为您最新收集整理,版权归原作者或公司所有。如有侵权,请与我们联系删除。
?上一文章:
?下一文章:商品名称:
评价得分:
其他谈论话题
多品类齐全,轻松购物
快多仓直发,极速配送
好正品行货,精致服务
省天天低价,畅选无忧最近有啥趣事?任天堂官方发布最新游戏主机 Nintendo Switch宣传视频?老罗发布新机并...
今年秋季苹果举行两场发布会,第一场是为新一代iPhone而举行的,而第二场则是为新的Ma...
如何保证产品的安全性不被轻易破解从而影响游戏体验或许将会成为一个主要的工作内容。
在坐等新品的同时,只想问问各位,买 iPhone 7 剁掉的手长回来了没?
如果属实,不知道到时候的iPhone质量会怎么样?
也许店员不能马上为你提供服务,但也不要这么冲动。
不过就目前来看,这项服务与国内用户没太大关系。
同样是正规 iPhone,为什么会出现价格不一样的情况呢?
DIGITAL MELODY GAMES 推出的新作向来比较休闲,但是却充满了创意,这一次的新作《假...
曾经开发过《恐怖传奇》、《乌鸦森林之谜》等经典互动解谜游戏的老牌开发商 Artifex M...
在上周四的更新当中,独立游戏开发团队 Seriously 就为全球的玩家带来了《呆萌小怪物...
《神奇的黄昏(Magic Nightfall)》是Grupo Promineo S.L.推出的一款三消类游戏,Grup...
生活的琐碎时常扰人清静,而已经习惯了此种生活的我们也逐渐开始用“忙”这个百试百灵...
此前由游戏开发商Kiwiwalks所制作的卡通风格的RPG游戏《春巫(WitchSpring)》中,我...
最近,育碧方面推出了一款名为《魔发精灵: 派对之森》的游戏,其“卡哇伊”的程度甚至...
告别多条数据线的杂乱,自带多款转接头的富基仕PowerGo移动电源于今日(10月26日)正...
和苹果AirPods一样,Powerbeats3同样配备了W1芯片。
Forcharge智能扩容电源盘于9月26日淘宝众筹正式开启,历时一个月众筹结束,共获得6147...
今天小编拿到了Anker PowerCore Fusion 5000 型移动电源,相比以往传统的移动电源,这...
不知道外媒评选的,合你的口味不~
这款采用了匹配的铝合金风格,造型更薄,目前已经在亚马逊上市,售价 39.99 美元。
不得不说,这个Note 7爆炸的梗还可以玩很久。
续航更持久,显然人人都喜欢。
大神,为什么我手机上可用内存和iTunes不同???
注册时间 最后登录
在线时间4 小时 UID
主题帖子人气
小苹果, 积分 18, 距离下一级还需 32 积分
5月3号入手的国行Plus,今天用iTunes备份信息,突然发现和手机上显示的剩余内存不一致,这是怎么回事啊?机器是电信营业厅买的,6088¥。
(83.07 KB, 下载次数: 2)
09:28 上传
(36.29 KB, 下载次数: 0)
09:29 上传
itunes 9.86g
注册时间 最后登录
在线时间170 小时 UID
主题帖子人气
11.56约等于11.6,手机上只能精确到小数点后一位
注册时间 最后登录
在线时间4 小时 UID
主题帖子人气
11.56约等于11.6,手机上只能精确到小数点后一位
请看剩余内存
注册时间 最后登录
在线时间1117 小时 UID
主题帖子人气
你的话 我连标点都不信
注册时间 最后登录
在线时间113 小时 UID
主题帖子人气
我的iPad也是…不知道为什么
注册时间 最后登录
在线时间49 小时 UID
主题帖子人气
威锋旗下产品
Hi~我是威威!
沪公网安备 29号 | 沪ICP备号-1
新三板上市公司威锋科技(836555)
增值电信业务经营许可证:
Powered by Discuz!android(3)
Android内存泄漏查找和解决
内存泄漏的概念
一个内存泄漏的例子
Java中”失效”的private修饰符
回头看内存泄漏例子泄漏的重点
强引用与弱引用
解决内部类的内存泄漏
Context造成的泄漏
使用LeakCanary工具查找内存泄漏
一.内存泄漏概念
1.什么是内存泄漏?
用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元。直到程序结束。即所谓的内存泄漏。
其实说白了就是该内存空间使用完毕之后未回收
2.内存泄漏会导致的问题
内存泄露就是系统回收不了那些分配出去但是又不使用的内存, 随着程序的运行,可以使用的内存就会越来越少,机子就会越来越卡,直到内存数据溢出,然后程序就会挂掉,再跟着操作系统也可能无响应。
(在我们平时写应用的过程中,可能会无意的写了一些存在内存泄漏的代码,如果没有专业的工具,对内存泄漏的原理也不熟悉,要查内存泄漏出现在哪里是比较困难的)接下来先看一个内存泄漏的例子
二.内存泄漏的例子
这个例子存在的问题应该很容易能看出来,使用了handler延迟一定时间执行Runnable代码块,而在Activity结束的时候又没有释放执行的代码块,导致了内存泄漏。那么只要在Activity结束onDestroy的时候,释放延迟执行的代码块不就可以了,确实是,那么再看一看下面的例子。
这段代码是实际开发中存在内存泄漏的实例,稍微进行简化得到的。内存泄漏的关键点在哪里,怎么去解决,先留着这个问题,看下面一节的内容:”失效”的private修饰符。
三.Java中”失效”的private修饰符
相信大家都用过内部类,Java允许在一个类里面定义另一个类,类里面的类就是内部类,也叫做嵌套类。一个简单的内部类实现可以如下
class OuterClass {
class InnerClass{
下面回头看上面写的例子:
这其实是一个我们在编程中经常用到的场景,就是在一个内部类里面访问外部类的private成员变量或者方法,这是可以的。
这是为什么,不是private修饰的成员只能被成员所述的类才能访问么?难道private真的失效了么?
其实是编译器帮我们做了一些我们看不到的工作,下面我们通过反编译把这些看不到的工作都扒出来看看
1.下面这一份是通过 dex2jar + jad 进行反编译得到的近似源码的java类
可以看到这份反编译出来的代码,比我们编写的源码,要多了一些东西,在内部类MyRunnable里面多了一个MainActivity的成员变量,并且,在构造函数里面获得了外部类的引用。
2.再看看下面这一份文件,这是通过 apktool 反编译出来的 smali指令语言
在这里MainActivity分成了两个文件,分别是MainActivity.smali和MainActivity$MyRunnable.smali。下面贴出的两份文件比较长,简单浏览一遍即可,详细看下面的解析,了解这份文件跟源码的对应关系。
MainActivity:
.class public Lcom/gexne/car/leaktest/MainA
.super Landroid/app/A
.source "MainActivity.java"
# annotations
.annotation system Ldalvik/annotation/MemberC
Lcom/gexne/car/leaktest/MainActivity$MyR
.end annotation
# instance fields
.field private handler:Landroid/os/H
.field private test:Ljava/lang/S
# direct methods
.method public constructor &init&()V
invoke-direct {p0}, Landroid/app/A-&&init&()V
const-string v0, "TEST_STR"
iput-object v0, p0, Lcom/gexne/car/leaktest/MainA-&test:Ljava/lang/S
new-instance v0, Landroid/os/H
invoke-direct {v0}, Landroid/os/H-&&init&()V
iput-object v0, p0, Lcom/gexne/car/leaktest/MainA-&handler:Landroid/os/H
return-void
.end method
.method static synthetic access$000(Lcom/gexne/car/leaktest/MainA)Ljava/lang/S
.param p0, "x0"
# Lcom/gexne/car/leaktest/MainA
iget-object v0, p0, Lcom/gexne/car/leaktest/MainA-&test:Ljava/lang/S
return-object v0
.end method
# virtual methods
.method protected onCreate(Landroid/os/B)V
.param p1, "savedInstanceState"
# Landroid/os/B
invoke-super {p0, p1}, Landroid/app/A-&onCreate(Landroid/os/B)V
const/high16 v0, 0x7f040000
invoke-virtual {p0, v0}, Lcom/gexne/car/leaktest/MainA-&setContentView(I)V
iget-object v0, p0, Lcom/gexne/car/leaktest/MainA-&handler:Landroid/os/H
new-instance v1, Lcom/gexne/car/leaktest/MainActivity$MyR
invoke-direct {v1, p0}, Lcom/gexne/car/leaktest/MainActivity$MyR-&&init&(Lcom/gexne/car/leaktest/MainA)V
const-wide/16 v2, 0x2710
invoke-virtual {v0, v1, v2, v3}, Landroid/os/H-&postDelayed(Ljava/lang/RJ)Z
invoke-virtual {p0}, Lcom/gexne/car/leaktest/MainA-&finish()V
return-void
.end method
在上面MainActivity.smali文件中,可以看到.field代表的是成员变量,.method代表的是方法,2个成员变量分别是Handler和String,方法则有3个分别是构造函数、onCreate()、access$000()。
嗯?在MainActivity中我们并没有定义access$000()这种方法,它是一个静态方法,接收一个MainActivity实例作为参数,并且返回MainActivity的test成员变量,所以,它出现的目的就是为了得到MainActivity的私有属性。
MainActivity$MyRunnable.smali:
.class Lcom/gexne/car/leaktest/MainActivity$MyRunnable;
.super Ljava/lang/Object;
.source "MainActivity.java"
.implements Ljava/lang/Runnable;
.annotation system Ldalvik/annotation/EnclosingClass;
value = Lcom/gexne/car/leaktest/MainActivity;
.end annotation
.annotation system Ldalvik/annotation/InnerClass;
accessFlags = 0x0
name = "MyRunnable"
.end annotation
.field final synthetic this$0:Lcom/gexne/car/leaktest/MainActivity;
.method constructor &init&(Lcom/gexne/car/leaktest/MainActivity;)V
.param p1, "this$0"
iput-object p1, p0, Lcom/gexne/car/leaktest/MainActivity$MyRunnable;-&this$0:Lcom/gexne/car/leaktest/MainActivity;
invoke-direct {p0}, Ljava/lang/Object;-&&init&()V
return-void
.end method
.method public run()V
const-string v0, "test"
iget-object v1, p0, Lcom/gexne/car/leaktest/MainActivity$MyRunnable;-&this$0:Lcom/gexne/car/leaktest/MainActivity;
invoke-static {v1}, Lcom/gexne/car/leaktest/MainActivity;-&access$000(Lcom/gexne/car/leaktest/MainActivity;)Ljava/lang/String;
move-result-object v1
invoke-static {v0, v1}, Landroid/util/Log;-&d(Ljava/lang/String;Ljava/lang/String;)I
return-void
.end method
MyRunnable.smali文件中用同样的方法观察,发现多了一个成员变量MainActivity,方法分别是构造函数、run(),根据smali指令的含义可以看到构造函数是接收了一个MainActivity作为参数的,而run()方法中获取外部类中的test变量,则是调用access$000()方法获取。如果想了解smali指令语言可以自行google,这里不详细讲解。通过上面两个文件,重新还原一下源码。
这段代码基本上还原了编译器编译后指令的执行方式。内部类调用外部类,是通过一个外部类的引用进行调用的(上面红色框框的两段代码是在还原的基础上加入的,用于解释内部类调用外部类的方式,调用方式1是我们常用的,而到的编译器编译后,实际调用方式是2),而外部类的private属性则通过编译器生成的我们看不见的静态方法,通过传入外部类实例引用获取出来。
通过还原,我们了解了非静态内部类跟外部类交互时的工作方式,以及非静态内部类为什么会持有外部类的引用。
四.通过dumpsys查看内存使用情况
继续回头看第一个内存泄漏的例子,稍微进行修改
对于这段代码,它会造成内存泄漏,那么对于外部类Activity来说,它能够被释放吗?
我们通过dumpsys来查看,了解怎么查看应用的内存使用情况,怎么看一个Activity有没有被顺利释放掉,而这个Activity能不能被回收。
1.先创建一个空Activity,如下代码所示,并安装到设备中
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
2.通过adb shell dumpsys meminfo &packageName&来查看内存使用状况
在没有打开应用的情况下,该命令返回的数据是这样的:
3.打开这个应用的MainActivity,再通过命令查看:
可以看到打印出来很多的信息,而对于我们查看Activity内存泄漏来说,只需要关注Activities和Views两个信息即可,在应用中存在的Activity对象有一个,存在的View对象有13个。
4.这时候我们退出这个Activity,在用命令查看一下:
可以看到,Activity对象和View对象都在极短的时间内被回收掉了。再次打开,退出,多次尝试,发现情况都是一样的。我们可以通过这种方式来简单判断一个Activity是否存在内存泄漏,最后是否能够被回收。
5.再运行刚才的泄漏的例子,用命令查看一下:
当我们连续打开退出同一个页面,然后使用命令查看时,发现Activity存在13个,而View则存在了234个,而且没有很快被回收,依次判断应该是存在内存泄漏了。
等待10多秒,再次查看,发现Activity和View的数量都变成了0。
所以,结论是能够被回收,只要Runnable代码块执行完毕,释放了Activity的引用,Activity就能被回收。
上面的例子,是Handler临时性内存泄漏,只要Handler post的代码块执行完毕,被引用的Activity就能够释放。
除了临时性内存泄漏,还有危害更大,直到程序结束才能被释放的内存泄漏。例如:
对于第一个例子,比较容易看出来,MyRunnable内部类持有了Activity的引用,而它自身一直不释放,导致Activity也一直无法释放,使用dumpsys meminfo查看可以验证,多次打开后退Activities的数量只会增加不会减少,直到手动结束整个应用。
而第二个例子也不难看出,只是引用链稍微长了点,TelephonyManager注册了内部类PhoneStateListener,持有了这个内部类的引用,PhoneStateListener持有了ViewHolder的引用,ViewHolder同时也是一个内部类,持有了ViewAdapter的引用,而ViewAdapter则持有了Activity的引用,最后TelephonyManager又没有做反注册的操作,导致了内存泄漏。
很多时候我们写代码,都忽略了释放工作,特别是写Java写多了,都觉得这些资源会自动释放,不用写释放方法,不用操心去做释放工作,然后内存泄漏就这样出现了。
参考资料:
五.强引用与弱引用
看完上面的例子,了解到非静态内部类因为持有外部类的引用,很可能会造成泄漏。为什么持有了外部类的引用会导致外部类不能被回收?
在解决内存泄漏之前,先了解Java的引用方式。Java有四种引用方式,分别是强引用、弱引用、虚引用、软引用。这里只介绍强引用以及弱引用,更详细的资料可以自行查找。
1.强引用(Strong Reference),就是我们经常使用的引用,写法如下
StringBuffer buffer = new StringBuffer();
上面创建了一个StringBuffer对象,并将这个对象的(强)引用存到变量buffer中。强引用最重要的就是它能够让引用变得强(Strong),这就决定了它和垃圾回收器的交互。具体来说,如果一个对象可以从GC Roots通过强引用到达时,那么这个对象将不会被GC回收。
2.弱引用(Weak Reference),弱引用简单来说就是将对象留在内存的能力不是那么强的引用。使用WeakReference,垃圾回收器会帮你来决定引用的对象何时回收并且将对象从内存移除。创建弱引用如下
WeakReference&Widget& weakWidget = new WeakReference&Widget&(widget);
使用weakWidget.get()就可以得到真实的Widget对象,因为弱引用不能阻挡垃圾回收器对其回收,你会发现(当没有任何强引用到widget对象时)使用get时突然返回null,所以对于弱引用要记得做判空处理后再使用,否则很容易出现NPE异常。
六.解决内部类的内存泄漏
通过上面介绍的内容,我们了解到内存泄漏产生的原因是对象在生命周期结束时被另一个对象通过强引用持有而无法释放造成的
怎么解决这个问题,思路就是避免使用非静态内部类,定义内部类时,要么是放在单独的类文件中,要么就是使用静态内部类。因为静态的内部类不会持有外部类的引用,所以不会导致外部类实例的内存泄露。当你需要在静态内部类中调用外部的Activity时,我们可以使用弱引用来处理。
这种解决方法,对于临时性内存泄漏适用,其中包括但不限于自定义动画的更新回调,网络请求数据后更新页面的回调等,更具体一点的例子有当我们在页面触发了网络请求加载时,希望它把数据加载完毕,当加载完毕时如果页面还在活动状态则更新显示内容。其实在Android中很多的内存泄露都是由于在Activity中使用了非静态内部类导致的,所以当我们使用时要非静态内部类时要格外注意。
在Android Studio里面,当你定义一个内部类Handler的时候,会出现贴心提示,This Handler class should be static or leaks might occur,提醒你把Handler改成静态类。
解决了上面的内存泄漏问题,再看看下面这个例子:
这个例子改写成静态内部类+弱引用,并不能完全解决内存泄漏的问题。
为什么?只需要加上一句Log即可验证。
多次进入退出页面,看一下打印出来的Log
结果显而易见,Log越来越多了,虽然Activity最后能够回收,但只是因为弱引用很弱,GC能够在内存不足的时候回收它,但并没有完全解决泄漏问题。
使用dumsys meminfo同样可以验证,每一次打开Activity并退出,等GC回收掉Activity后,发现Local Binder的数量并没有减少,而且比上一次多了1。
对于注册到服务中的回调(包括系统服务,自定义服务),使用静态内部类+弱引用的方式只能部分解决内存泄漏问题,这种问题需要释放资源时进行反注册才能根本解决,因为这种服务会长期存在系统中,注册了的callback对象会一直存在于服务中,每次callback来了都会执行callback中的代码块,只不过执行到弱引用部分由于弱引用获取到的对象为null而不会执行下一步操作。例如Broadcast,例如systemServer.listen等。
七.Context造成的泄漏
了解完内部类的泄漏以及修复方法,再来看一下另一种泄漏,由context造成的泄漏。
这也是一个开发中的例子,稍作修改得到。
可以看到,蓝色框框内是一个标准的懒汉式单例。单例是我们比较简单常用的一种设计模式,然而如果单例使用不当也会导致内存泄露。比如这个例子,DashBoardTypeface需要持有一个Context作为成员变量,并且使用该Context创建字体资源。
instance作为静态对象,其生命周期要长于普通的对象,其中也包含Activity,当我们退出Activity,默认情况下,系统会销毁当前Activity,然后当前的Activity被一个单例持有,导致垃圾回收器无法进行回收,进而产生了内存泄露。
解决的方法就是不持有Activity的引用,而是持有Application的Context引用。
在任何使用到Context的地方,都要多加注意,例如我们常见的Dialog,Menu,悬浮窗,这些控件都需要传入Context作为参数的,如果要使用Activity作为Context参数,那么一定要保证控件的生命周期跟Activity的生命周期同步。窗体泄漏也是内存泄漏的一种,就是我们常见的leak window,这种错误就是依赖Activity的控件生命周期跟Activity不同步造成的。
一般来说,对于非控件类型的对象需要Context参数,最好优先考虑全局ApplicationContext,来避免内存泄漏。
参考资料:
八.使用LeakCanary工具查找内存泄漏
LeakCanary是什么?它是一个傻瓜化并且可视化的内存泄露分析工具。
它的特点是简单,易于发现问题,人人都可参与,只要配置完成,简单的黑盒测试通过手工点击就能够看到详细的泄漏路径。
下面来看一下如何集成:
dependencies {
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.4-beta2'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2'
testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2'
创建Application并加入LeakCanary代码:
public class ExampleApplication extends Application {
@Override public void onCreate() {
super.onCreate();
LeakCanary.install(this);
这样已经完成最简单的集成,可以开始进行测试了。
在进行尝试之前再看一段代码:
思考完这段代码的问题后,我们来尝试一下使用LeakCanary寻找问题。如上面的配置,配置好应用,安装后可以看到,应用多了一个入口,如图所示。
这个入口就是当应用在使用过程中发生内存泄漏,可以从这个入口看到详细的泄漏位置。
从LeakCanary给出来的分析能轻易找到内存泄漏出现在responseHandler里面,跟刚才思考分析的答案是否一致呢?如果一致那你对内存泄漏的知识已经掌握不少了。
上面这种是最简单的默认配置,只对Activity进行了检测。但需要检测的对象肯定不只有Activity,例如Fragment、Service、Broadcast。这需要做更多的配置,在Application中留下RefWatcher的引用,使用它来检测其他对象。
public class MyApplication extends Application {
private static RefWatcher sRefW
public void onCreate() {
super.onCreate();
sRefWatcher = LeakCanary.install(this);
public static RefWatcher getRefWatcher() {
return sRefW
在有生命周期的对象的onDestroy()中进行监控,例如Service。
public class CoreService extends Service {
public void onDestroy() {
super.onDestroy();
MyApplication.getRefWatcher().watch(this);
监控需要设置在对象(很快)被释放的时候,如Activity和Fragment的onDestroy方法。
一个错误示例,比如监控一个Activity,放在onCreate就会大错特错了,那么你每次都会收到Activity的泄露通知。
更详细的资料可以到LeakCanary的github仓库中查看。
关于内存泄漏的知识,如何定位内存泄漏,如何修复,已经讲解完了。
最后做一个总结:
非静态内部类的静态实例
非静态内部类会维持一个到外部类实例的引用,如果非静态内部类的实例是静态的,就会间接长期维持着外部类的引用,阻止被回收掉。
资源对象未关闭
资源性对象如Cursor、File、Socket,应该在使用后及时关闭。未在finally中关闭,会导致异常情况下资源对象未被释放的隐患。
注册对象未反注册
未反注册会导致观察者列表里维持着对象的引用,阻止垃圾回收。
Handler临时性内存泄露
Handler通过发送Message与主线程交互,Message发出之后是存储在MessageQueue中的,有些Message也不是马上就被处理的。在Message中存在一个 target,是Handler的一个引用,如果Message在Queue中存在的时间越长,就会导致Handler无法被回收。如果Handler是非静态的,则会导致Activity或者Service不会被回收。
由于AsyncTask内部也是Handler机制,同样存在内存泄漏的风险。
此种内存泄露,一般是临时性的。
不要维持到Activity的长久引用,对activity的引用应该和activity本身有相同的生命周期。
尽量使用context-application代替context-activity
Activity中尽量不要使用非静态内部类,可以使用静态内部类和WeakReference代替。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:10525次
排名:千里之外
评论:21条}

我要回帖

更多关于 与卖家协商一致退款 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信