Android內存優化——內存泄露檢測分析方法

上一篇文章總結了一些常見的內存泄露場景及優化方案,這篇文章繼續總結內存泄露的一些常用的檢測和分析方法。

Lint代碼檢查

AndroidStudio自動Lint代碼檢查工具,一些常見的代碼警告Lint工具都會給我們提示。使用也比較簡單:

Analyze —> Inspect Code 然后選擇檢查范圍:

Lint使用-1

Lint使用-2

Lint使用-3

比如如果存在非靜態內部類的Handler,可能會導致內存泄露,檢查結果就會顯示在AndroidStudio的控制臺。

其實,只要我們在設置里面勾選了Lint代碼檢查(AnroidStudio默認是勾選了的),在寫代碼的時候就會自動提示可能發生內存泄露。

Lint檢查代碼內存泄露

Lint提示內存泄露

通常在寫Handler、靜態字段、標記對象等可能存在的內存泄露時,Lint檢查工具都會有一個警告提示信息,我們可以根據Lint檢查的提示信息來避免這些有可能發生的內存泄露。

Android Monitor

在AndroidStudio中,可以通過Monitors來監控Memory、CPU、Network、GPU等。在Monitors監控中,我們可以獲取內存的各種信息來分析內存泄露。

首先運行工程后,打開控制臺的Android Monitor:

Android Monitor

在運行設備中使用app(各個頁面的跳轉,使用相應的各種功能),就可以看到內存使用的不斷變化:

內存使用變化

淡藍色和淺灰色區域就是內存分配的變化過程,淺灰色表示空閑內存,淡藍色表示使用內存。

通常,我們在打開一個新的頁面后,使用的內存就會增加,相應的,關閉一個頁面后,系統執行了GC,使用的內存應該下降。如果我們在退出界面并執行GC后,內存使用并未下降明顯,或者使用內存沒有下降初始的使用大小,那么有可能就發生了內存泄露。

運行工程,在設備上操作app,觀察Monitor中內存的變化,點擊 initiate GC 觸發GC,然后點擊Dump Java Heap轉出堆信息,稍等片刻,生成hprof文件,生成后會在Studio中自動打開。

hprof文件

點擊右側的Analyzer Tasks,再點擊Perform Analyzer,展開下面分析結果
中的 Leaked Activities 就可以看到發生內存泄露的Activity了。

Monitor內存泄露分析

可以根據左側的引用樹,來查找持有Activity引用的位置,從而判斷出哪個地方導致了內存泄露。

Mat

使用第三方的Mat工具來分析內存泄露,需要在官網下載獨立版的Mat。

將Android Monitor生成的hprof文件導出為標準的hprof文件(必須這樣導出,直接copy出來會報錯的):

導出hprof文件

使用Mat打開導出的hprof文件:

Mat打開hprof文件

點擊Histogram(直方圖),可以看到類對應的實例數量的統計。

直方圖

在Class Name下面輸入需要匹配的類名,根據類來查看它的實例的引用,進而分析是否存在內存泄露。

類的實例

可以看到TestActivity和MyHandler都只有一個實例被引用。

TestActivity點擊右鍵—>Merge Shortest Paths to GC Roots —>exclude all phantom/weak/soft etc.references。

Merge Shortest Paths to GC Roots 可以查看一個對象到RC Roots是否存在引用鏈相連接, 在JAVA中是通過可達性(Reachability Analysis)來判斷對象是否存活,這個算法的基本思想是通過一系列的稱謂"GC Roots"的對象作為起始點,從這些節點開始向下搜索,搜索所走得路徑稱為引用鏈,當一個對象到GC Roots沒有任何引用鏈相連則該對象被判定為可以被回收的對象,反之不能被回收,我們可以選擇 exclude all phantom/weak/soft etc.references(排查虛引用/弱引用/軟引用等)因為被虛引用/弱引用/軟引用的對象可以直接被GC給回收。

參考自Android 性能優化之使用MAT分析內存泄露問題。

TestActivity實例 RC Roots引用鏈

可以看到TestActivity實例存在GC Roots鏈,TextActivity實例被mMessageQueue.mMessae.target.this$0持有,那么發生了內存泄露,我們可以根據引用鏈來在代碼中找到內存泄露的位置。

LeakCanary

LeakCanary是square開源的檢測內存泄露的第三方庫。它最大的有點就是開發者只需要添加簡單代碼,app在運行時如果發生了內存泄露,就會很直觀的將內存泄露的詳細信息展示在通知欄上,這樣避免了Android Monitor或者Mat等工具的繁瑣的分析過程。

項目地址:github.com/square/leak…

在Gradle文件中添加依賴:

 dependencies {debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5'releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'}復制代碼

在入口的Application中進行初始化:

public class App extends Application {// 模擬內存泄露場景public static ArrayList<Activity> sActivities = new ArrayList<>();@Overridepublic void onCreate() {super.onCreate();if (LeakCanary.isInAnalyzerProcess(this)) {// This process is dedicated to LeakCanary for heap analysis.// You should not init your app in this process.return;}LeakCanary.install(this);// Normal app init code...}
}復制代碼

在Application中新建一個靜態List,里面存儲Activity,來模擬內存泄露案例:

public class TestActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_test);App.sActivities.add(this);}public void back(View view) {finish();}
}復制代碼

運行app后,在控制臺可以看到LeakCanary的日志:

04-25 10:20:46.793 D/LeakCanary: In com.xiao.memoryleakexample:1.0:1.
04-25 10:20:46.793 D/LeakCanary: * com.xiao.memoryleakexample.TestActivity has leaked:
04-25 10:20:46.793 D/LeakCanary: * GC ROOT static com.xiao.memoryleakexample.app.App.sActivities
04-25 10:20:46.793 D/LeakCanary: * references java.util.ArrayList.array
04-25 10:20:46.793 D/LeakCanary: * references array java.lang.Object[].[0]
04-25 10:20:46.793 D/LeakCanary: * leaks com.xiao.memoryleakexample.TestActivity instance
04-25 10:20:46.793 D/LeakCanary: * Retaining: 88 KB.
04-25 10:20:46.793 D/LeakCanary: * Reference Key: 915bf11a-db9f-468e-8064-d6fb103710e9
04-25 10:20:46.793 D/LeakCanary: * Device: OPPO OPPO OPPO R9 Plusm A R9PlusmA
04-25 10:20:46.793 D/LeakCanary: * Android Version: 5.1.1 API: 22 LeakCanary: 1.5 00f37f5
04-25 10:20:46.793 D/LeakCanary: * Durations: watch=5049ms, gc=207ms, heap dump=979ms, analysis=122889ms
04-25 10:20:46.793 D/LeakCanary: * Details:
04-25 10:20:46.793 D/LeakCanary: * Class com.xiao.memoryleakexample.app.App
04-25 10:20:46.793 D/LeakCanary: |   static $staticOverhead = byte[24]@314667009 (0x12c17001)
04-25 10:20:46.793 D/LeakCanary: |   static sActivities = java.util.ArrayList@315492800 (0x12ce09c0)
04-25 10:20:46.793 D/LeakCanary: |   static serialVersionUID = -920324649544707127
04-25 10:20:46.793 D/LeakCanary: |   static $change = null
04-25 10:20:46.793 D/LeakCanary: * Instance of java.util.ArrayList
04-25 10:20:46.793 D/LeakCanary: |   static $staticOverhead = byte[16]@1893824473 (0x70e177d9)
04-25 10:20:46.793 D/LeakCanary: |   static MIN_CAPACITY_INCREMENT = 12
04-25 10:20:46.793 D/LeakCanary: |   static serialVersionUID = 8683452581122892189
04-25 10:20:46.793 D/LeakCanary: |   array = java.lang.Object[12]@318048768 (0x12f50a00)
04-25 10:20:46.793 D/LeakCanary: |   size = 1
04-25 10:20:46.793 D/LeakCanary: |   modCount = 1
04-25 10:20:46.793 D/LeakCanary: * Array of java.lang.Object[]
04-25 10:20:46.793 D/LeakCanary: |   [0] = com.xiao.memoryleakexample.TestActivity@316091520 (0x12d72c80)
04-25 10:20:46.793 D/LeakCanary: |   [1] = null
04-25 10:20:46.793 D/LeakCanary: |   [2] = null
04-25 10:20:46.793 D/LeakCanary: |   [3] = null
04-25 10:20:46.793 D/LeakCanary: |   [4] = null
04-25 10:20:46.793 D/LeakCanary: |   [5] = null
04-25 10:20:46.793 D/LeakCanary: |   [6] = null
04-25 10:20:46.793 D/LeakCanary: |   [7] = null
04-25 10:20:46.793 D/LeakCanary: |   [8] = null
04-25 10:20:46.793 D/LeakCanary: |   [9] = null
04-25 10:20:46.793 D/LeakCanary: |   [10] = null
04-25 10:20:46.793 D/LeakCanary: |   [11] = null
04-25 10:20:46.793 D/LeakCanary: * Instance of com.xiao.memoryleakexample.TestActivity
04-25 10:20:46.793 D/LeakCanary: |   static $staticOverhead = byte[16]@316125185 (0x12d7b001)
04-25 10:20:46.793 D/LeakCanary: |   static serialVersionUID = 836998863274086997
04-25 10:20:46.793 D/LeakCanary: |   static $change = null
04-25 10:20:46.793 D/LeakCanary: |   mHandler = com.xiao.memoryleakexample.TestActivity$MyHandler@318005952 (0x12f462c0)
04-25 10:20:46.793 D/LeakCanary: |   mDelegate = android.support.v7.app.AppCompatDelegateImplV14@314816320 (0x12c3b740)
04-25 10:20:46.793 D/LeakCanary: |   mEatKeyUpEvent = false
04-25 10:20:46.793 D/LeakCanary: |   mResources = null
04-25 10:20:46.793 D/LeakCanary: |   mThemeId = 2131230884
04-25 10:20:46.793 D/LeakCanary: |   mCreated = true
04-25 10:20:46.793 D/LeakCanary: |   mFragments = android.support.v4.app.FragmentController@317876896 (0x12f26aa0)
04-25 10:20:46.793 D/LeakCanary: |   mHandler = android.support.v4.app.FragmentActivity$1@318005920 (0x12f462a0)
04-25 10:20:46.793 D/LeakCanary: |   mNextCandidateRequestIndex = 0
04-25 10:20:46.793 D/LeakCanary: |   mOptionsMenuInvalidated = false
04-25 10:20:46.793 D/LeakCanary: |   mPendingFragmentActivityResults = android.support.v4.util.SparseArrayCompat@318008352 (0x12f46c20)
04-25 10:20:46.793 D/LeakCanary: |   mReallyStopped = true
04-25 10:20:46.793 D/LeakCanary: |   mRequestedPermissionsFromFragment = false
04-25 10:20:46.793 D/LeakCanary: |   mResumed = false
04-25 10:20:46.793 D/LeakCanary: |   mRetaining = false
04-25 10:20:46.793 D/LeakCanary: |   mStopped = true
04-25 10:20:46.793 D/LeakCanary: |   mStartedActivityFromFragment = false
04-25 10:20:46.793 D/LeakCanary: |   mStartedIntentSenderFromFragment = false
04-25 10:20:46.793 D/LeakCanary: |   mExtraDataMap = android.support.v4.util.SimpleArrayMap@318005888 (0x12f46280)
04-25 10:20:46.793 D/LeakCanary: |   mActionBar = null
04-25 10:20:46.793 D/LeakCanary: |   mActivityInfo = android.content.pm.ActivityInfo@318009472 (0x12f47080)
04-25 10:20:46.793 D/LeakCanary: |   mActivityTransitionState = android.app.ActivityTransitionState@317937344 (0x12f356c0)
04-25 10:20:46.793 D/LeakCanary: |   mAllLoaderManagers = android.util.ArrayMap@318081312 (0x12f58920)
04-25 10:20:46.793 D/LeakCanary: |   mApplication = com.xiao.memoryleakexample.app.App@315492832 (0x12ce09e0)
04-25 10:20:46.793 D/LeakCanary: |   mCalled = true
04-25 10:20:46.793 D/LeakCanary: |   mChangeCanvasToTranslucent = false
04-25 10:20:46.793 D/LeakCanary: |   mChangingConfigurations = false
04-25 10:20:46.793 D/LeakCanary: |   mCheckedForLoaderManager = true
04-25 10:20:46.793 D/LeakCanary: |   mComponent = android.content.ComponentName@314990768 (0x12c660b0)
04-25 10:20:46.793 D/LeakCanary: |   mConfigChangeFlags = 0
04-25 10:20:46.793 D/LeakCanary: |   mContainer = android.app.Activity$1@317876848 (0x12f26a70)
04-25 10:20:46.793 D/LeakCanary: |   mCurrentConfig = android.content.res.Configuration@317856672 (0x12f21ba0)
04-25 10:20:46.793 D/LeakCanary: |   mDecor = null
04-25 10:20:46.793 D/LeakCanary: |   mDefaultKeyMode = 0
04-25 10:20:46.793 D/LeakCanary: |   mDefaultKeySsb = null
04-25 10:20:46.793 D/LeakCanary: |   mDestroyed = true
04-25 10:20:46.793 D/LeakCanary: |   mDoReportFullyDrawn = false
04-25 10:20:46.793 D/LeakCanary: |   mEmbeddedID = null
04-25 10:20:46.793 D/LeakCanary: |   mEnableDefaultActionBarUp = false
04-25 10:20:46.793 D/LeakCanary: |   mEnterTransitionListener = android.app.SharedElementCallback$1@1893595344 (0x70ddf8d0)
04-25 10:20:46.793 D/LeakCanary: |   mExitTransitionListener = android.app.SharedElementCallback$1@1893595344 (0x70ddf8d0)
04-25 10:20:46.793 D/LeakCanary: |   mFinished = true
04-25 10:20:46.793 D/LeakCanary: |   mFragments = android.app.FragmentManagerImpl@317856448 (0x12f21ac0)
04-25 10:20:46.793 D/LeakCanary: |   mHandler = android.os.Handler@318005856 (0x12f46260)
04-25 10:20:46.793 D/LeakCanary: |   mIdent = 578025123
04-25 10:20:46.793 D/LeakCanary: |   mInstanceTracker = android.os.StrictMode$InstanceTracker@317876864 (0x12f26a80)
04-25 10:20:46.793 D/LeakCanary: |   mInstrumentation = android.app.Instrumentation@315352176 (0x12cbe470)
04-25 10:20:46.793 D/LeakCanary: |   mIntent = android.content.Intent@317362304 (0x12ea9080)
04-25 10:20:46.793 D/LeakCanary: |   mLastNonConfigurationInstances = null
04-25 10:20:46.793 D/LeakCanary: |   mLoaderManager = null
04-25 10:20:46.793 D/LeakCanary: |   mLoadersStarted = false
04-25 10:20:46.793 D/LeakCanary: |   mMainThread = android.app.ActivityThread@314856000 (0x12c45240)
04-25 10:20:46.803 D/LeakCanary: |   mManagedCursors = java.util.ArrayList@318005792 (0x12f46220)
04-25 10:20:46.803 D/LeakCanary: |   mManagedDialogs = null
04-25 10:20:46.803 D/LeakCanary: |   mMenuInflater = null
04-25 10:20:46.803 D/LeakCanary: |   mParent = null
04-25 10:20:46.803 D/LeakCanary: |   mReferrer = java.lang.String@314984512 (0x12c64840)
04-25 10:20:46.803 D/LeakCanary: |   mResultCode = 0
04-25 10:20:46.803 D/LeakCanary: |   mResultData = null
04-25 10:20:46.803 D/LeakCanary: |   mResumed = false
04-25 10:20:46.803 D/LeakCanary: |   mSearchManager = null
04-25 10:20:46.803 D/LeakCanary: |   mStartedActivity = false
04-25 10:20:46.803 D/LeakCanary: |   mStopped = true
04-25 10:20:46.803 D/LeakCanary: |   mTemporaryPause = false
04-25 10:20:46.803 D/LeakCanary: |   mTitle = java.lang.String@316164352 (0x12d84900)
04-25 10:20:46.803 D/LeakCanary: |   mTitleColor = 0
04-25 10:20:46.803 D/LeakCanary: |   mTitleReady = true
04-25 10:20:46.803 D/LeakCanary: |   mToken = android.os.BinderProxy@314983040 (0x12c64280)
04-25 10:20:46.803 D/LeakCanary: |   mTranslucentCallback = null
04-25 10:20:46.803 D/LeakCanary: |   mUiThread = java.lang.Thread@1967775656 (0x7549dfa8)
04-25 10:20:46.803 D/LeakCanary: |   mVisibleBehind = false
04-25 10:20:46.803 D/LeakCanary: |   mVisibleFromClient = true
04-25 10:20:46.803 D/LeakCanary: |   mVisibleFromServer = true
04-25 10:20:46.803 D/LeakCanary: |   mVoiceInteractor = null
04-25 10:20:46.803 D/LeakCanary: |   mWindow = com.android.internal.policy.impl.PhoneWindow@315631936 (0x12d02940)
04-25 10:20:46.803 D/LeakCanary: |   mWindowAdded = true
04-25 10:20:46.803 D/LeakCanary: |   mWindowManager = android.view.WindowManagerImpl@318006848 (0x12f46640)
04-25 10:20:46.803 D/LeakCanary: |   mInflater = com.android.internal.policy.impl.PhoneLayoutInflater@317929312 (0x12f33760)
04-25 10:20:46.803 D/LeakCanary: |   mOverrideConfiguration = null
04-25 10:20:46.803 D/LeakCanary: |   mResources = android.content.res.Resources@314591360 (0x12c04880)
04-25 10:20:46.803 D/LeakCanary: |   mTheme = android.content.res.Resources$Theme@318006400 (0x12f46480)
04-25 10:20:46.803 D/LeakCanary: |   mThemeResource = 2131230884
04-25 10:20:46.803 D/LeakCanary: |   mBase = android.app.ContextImpl@317145792 (0x12e742c0)
04-25 10:20:46.803 D/LeakCanary: * Excluded Refs:
04-25 10:20:46.803 D/LeakCanary: | Field: android.view.inputmethod.InputMethodManager.mNextServedView
04-25 10:20:46.803 D/LeakCanary: | Field: android.view.inputmethod.InputMethodManager.mServedView
04-25 10:20:46.803 D/LeakCanary: | Field: android.view.inputmethod.InputMethodManager.mServedInputConnection
04-25 10:20:46.803 D/LeakCanary: | Field: android.view.inputmethod.InputMethodManager.mCurRootView
04-25 10:20:46.803 D/LeakCanary: | Field: android.animation.LayoutTransition$1.val$parent
04-25 10:20:46.803 D/LeakCanary: | Field: android.view.textservice.SpellCheckerSession$1.this$0
04-25 10:20:46.803 D/LeakCanary: | Field: android.support.v7.internal.widget.ActivityChooserModel.mActivityChoserModelPolicy
04-25 10:20:46.803 D/LeakCanary: | Field: android.widget.ActivityChooserModel.mActivityChoserModelPolicy
04-25 10:20:46.803 D/LeakCanary: | Field: android.accounts.AccountManager$AmsTask$Response.this$1
04-25 10:20:46.803 D/LeakCanary: | Field: android.media.MediaScannerConnection.mContext
04-25 10:20:46.803 D/LeakCanary: | Field: android.os.UserManager.mContext
04-25 10:20:46.803 D/LeakCanary: | Field: android.media.AudioManager$1.this$0
04-25 10:20:46.803 D/LeakCanary: | Field: android.widget.Editor$Blink.this$0
04-25 10:20:46.803 D/LeakCanary: | Field: android.net.ConnectivityManager.sInstance
04-25 10:20:46.803 D/LeakCanary: | Field: android.view.Choreographer$FrameDisplayEventReceiver.mMessageQueue (always)
04-25 10:20:46.803 D/LeakCanary: | Static field: android.text.TextLine.sCached
04-25 10:20:46.803 D/LeakCanary: | Thread:FinalizerWatchdogDaemon (always)
04-25 10:20:46.803 D/LeakCanary: | Thread:main (always)
04-25 10:20:46.803 D/LeakCanary: | Thread:LeakCanary-Heap-Dump (always)
04-25 10:20:46.803 D/LeakCanary: | Class:java.lang.ref.WeakReference (always)
04-25 10:20:46.803 D/LeakCanary: | Class:java.lang.ref.SoftReference (always)
04-25 10:20:46.803 D/LeakCanary: | Class:java.lang.ref.PhantomReference (always)
04-25 10:20:46.803 D/LeakCanary: | Class:java.lang.ref.Finalizer (always)
04-25 10:20:46.803 D/LeakCanary: | Class:java.lang.ref.FinalizerReference (always)復制代碼

日志當中展示了詳細的內存泄露信息。同時,在運行設備上,會以通知的形式展示內存泄露:

LeakCanary內存泄露通知

點擊通知欄后會展示消息的內存泄露信息,包括泄露的具體實例、以及發生在哪個類中的具體引用位置:

LeakCanary內存泄露詳細信息-1

LeakCanary內存泄露詳細信息-2

最后

Lint、Android Monitor、Mat,以及LeakCanary都能讓我們在平常的開發過程中非常有效的避免內存泄露,至于選擇哪個工具,那種方式,就看自己平常的習慣了。個人還是更喜歡使用LeakCanary,只需要簡單的集成,就可以更加快速,直觀展示內存泄露的信息。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/396097.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/396097.shtml
英文地址,請注明出處:http://en.pswp.cn/news/396097.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ImageLoader加載圖片

先導universal-image-loader-1.9.3包 在application配置 android:name".MyApplication" intent權限 1 package com.ch.day13_imageloaderdemo;2 3 import java.io.File;4 5 import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache; 6 impor…

hackintosh黑蘋果_為什么您的下一個Mac應該是Hackintosh?

hackintosh黑蘋果by Sebastian Dobrincu塞巴斯蒂安多布林庫(Sebastian Dobrincu) 為什么您的下一個Mac應該是Hackintosh&#xff1f; (Why Your Next Mac Should Be a Hackintosh ?) I just finished a 48-hour Hackintosh building marathon. It was a fun experience and I…

一張圖解釋什么是遺傳算法_遺傳算法簡介及代碼詳解

(allele)數據值&#xff0c;屬性&#xff0c;值基因座(locus)位置&#xff0c;iterator位置表現型(phenotype)參數集&#xff0c;解碼結構&#xff0c;候選解染色體&#xff1a;又可以叫做基因型個體(individuals)群體/種群(population)&#xff1a;一定數量的個體組成&#xf…

c語言程序設計學生程序查詢,《c語言程序設計報告-學生信息管理系統》.doc

《c語言程序設計報告-學生信息管理系統》中南大學??C語言程序設計實踐報告?????題 目 學生信息管理系統學生姓名 張眼指導教師 劉偉榮學 院 信息科學與工程學院專業班級 電氣信息1113班完成時間 2012年6月28日星期四?1.設計任務及設計目標學生信息管理系統是基于系統主…

ListString 和 ArrayListString的區別

最近對這兩個問題比較懵逼&#xff0c;關于List和ArrayList、List<String> list new ArrayList<String>(); 好了&#xff0c;先搞明白List 和 ArrayList吧。 List是一個接口&#xff0c;是Collection接口的一個子接口&#xff0c;是一個有序的集合。 ArrayList是L…

java城市級聯一次查詢_我的城市沒有任何設計活動,所以我自己組織了一次。...

java城市級聯一次查詢by Marty Laurita由Marty Laurita 我的城市沒有任何設計活動&#xff0c;所以我自己組織了一次。 (There weren’t any design events in my city, so I organized one myself.) “The meeting of two personalities is like the contact of two chemical…

Access denied for user 'root'@'localhost' (using password: YES) 問題解決小記

初學php&#xff0c;按照視頻安裝后好mysql后 終端運行命令 mysql -u root -p 然后輸入安裝mysql時輸入的密碼六個1&#xff0c;會報這樣的錯誤&#xff1a;Access denied for user rootlocalhost (using password: YES) &#xff1b; 百度了一大堆&#xff0c;大海撈針一般找…

匯編總結2

一、寄存器 一個典型的cpu是由運算器&#xff0c;控制器&#xff0c;寄存器等器件組成的。 內部總線實現CPU內部各個器件之間的聯系 外部總線實現cpu和主板上其他器件的聯系 AX,BX,CX,DX通用寄存器 SI,DI,BP,SP基址和變址寄存器 CS,SS,DS,ES段寄存器 IP,FLAGS指令指針和標志寄存…

創業者具備的五大技能_一、如今大學生創業需要具備哪些知識與技能?

我參加過兩次互聯網&#xff0b;大賽&#xff0c;分別獲得過省賽的金獎與銀獎&#xff0c;還曾參加山東省大大小小比賽26場&#xff0c;金獎累計獲得12次。對當代創業的大學生所應具備哪些基本素質深有體會。&#xff08;1&#xff09;技能&#xff1a;1、自我認知及科學規劃能…

c語言定時器回調函數的參數,定時器的簡單實現即回調函數的運用

&#xfeff;&#xfeff;這兩天在 研究回調函數就想實現簡單的定時器&#xff0c;如下是鄙人的程序望指教。ios#include #include using namespace std;app#define MAXNUM 256函數typedef void (*timerProcessFunc)(void*);spatypedef struct{unsigned int id;int timeout; /…

BZOJ3387柵欄行動

首先&#xff0c;很容易想到Dp。設f[i][0]表示第i個柵欄走左邊的最短路&#xff0c;f[i][1]表示第i個柵欄走右邊的最短路。 所以&#xff0c;我們要找一個剛好在第i個柵欄的左右邊界下面的柵欄。如圖所示&#xff1a; 則有&#xff1a; f[i][0] min(f[k][0] |Left[i] - Left[…

udacity開源的數據_評論:Udacity數據分析師納米學位計劃

udacity開源的數據by David Venturi大衛文圖里(David Venturi) 評論&#xff1a;Udacity數據分析師納米學位計劃 (Review: Udacity Data Analyst Nanodegree Program) Udacity’s Data Analyst Nanodegree program was one of the first online data science programs in the …

凌晨四點鐘深圳的風景

科比有過一句很勵志的故事&#xff1a;凌晨四點鐘洛杉磯的風景。 很多人把科比當成榜樣&#xff0c;不僅僅因為他精湛的球技&#xff0c;更是因為他遠超常人的職業精神。 其實做到這一點&#xff0c;并不難&#xff0c;難的是堅持。堅持那么早時間起床&#xff0c;堅持十年如一…

小程序沉浸式_古北水鎮紅葉祭嵌入戲精學院 全新文旅沉浸模式讓游客嗨起來...

2020年10月17日-24日&#xff0c;古北水鎮第二屆紅葉祭火熱來襲。今年除了“超級漫展二次元度假”的模式&#xff0c;古北水鎮與頂級沉浸互動體驗運營方——INX戲精學院合作&#xff0c;在深度體驗空間的同時&#xff0c;加入了互動式的實景游戲體驗&#xff0c;通過演員互動&a…

又拍云劉平陽,理性競爭下的技術品牌提升之道

云服務市場趨漸平穩&#xff0c;在這種情況下&#xff0c;就需要通過對某一項技術的深入應用來實現服務的精致化。同時&#xff0c;對品牌的打造和包裝也必不可少。\\又拍云在2010年開始提供云服務&#xff0c;經過多年的發展&#xff0c;以及市場策略的轉變&#xff0c;決定對…

編寫代碼的工作在哪找_編寫事件代碼如何幫助我獲得了出色的工作

編寫代碼的工作在哪找Everyone kept telling me about the importance of networking, but it was always something I blew off. I’m pretty quiet and introverted, particularly when meeting strangers. I thought I just wasn’t built for networking.每個人都在不斷告訴…

int x = 0x13 c語言,2004年7月全國高等教育自學考試微型計算機原理與接口技術試題...

課程代碼&#xff1a;02205第一部分 C語言程序設計一、單項選擇題(在每小題的四個備選答案中&#xff0c;選出一個正確答案&#xff0c;并將正確答案的序號填在題干的括號內。每小題2分&#xff0c;共10分)1.4位無符號二進制數表示的數的范圍是( )。A.0&#xff5e;9999 B.…

iOS開發簡單高效的數據存儲

在iOS開發過程中&#xff0c;不管是做什么應用&#xff0c;都會碰到數據保存的問題&#xff0c;你是用什么方法來持久保存數據的&#xff1f;這是在幾乎每一次關于iOS技術的交流或討論都會被提到的問題&#xff0c;而且大家對這個問題的熱情持續高漲。本文主要從概念上把“數據…

Oracle中Date和Timestamp的區別

Date和Timestamp精度不一樣&#xff1a; 01&#xff09;Timestamp精確到了秒的小數點&#xff08;如&#xff1a;2018-11-13 16:40:03.698&#xff09;&#xff1b; 02&#xff09;Date只精確到整數的秒&#xff08;如&#xff1a;2018-11-13 16:40:03&#xff09; 轉載于:http…

table偏見和HTML仇外心理

by Anthony Ng由Anthony Ng <table>偏見和HTML仇外心理 (<table> prejudice and HTML xenophobia) I was looking over some HTML with a student the other day when we stumbled onto a <table>.前幾天&#xff0c;當我偶然發現一個<table>時&#…