首页 文章 精选 留言 我的

精选列表

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

MaxCompute 费用暴涨之存储压缩率降低导致SQL输入量变大

现象:同样的SQL,每天处理的数据行数差不多,但是费用突然暴涨甚至会翻数倍。 分析: 我们先明确MaxCompute SQL后付费的计费公式:一条SQL执行的费用=扫描输入量 ️ SQL复杂度 ️ 0.3(¥/GB)。 变量主要是输入量和复杂度,如果SQL没有变更的情况下复杂度度也没有变化,那么费用上涨主要原因就是输入量增加,因此我们侧重从输入量去排查是什么环节导致来了输入量的增加。 排查: 挑两个job的Logview查看输入量,推荐用MaxCompute Studio的作业对比功能查看,作业对比功能使用方式可以参考《MaxCompute Studio使用心得系列7——作业对比》。输入量如下: 如上图,数据行数差别没有翻倍,但是大小(bytes)翻倍,基本可以排除是因为数据量暴增导致。那么数据行数增量不大,但是数据大小翻倍,无疑翻倍的这些数

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

一种提高Android应用进程存活率新方法(上)

基础知识 Android 进程优先级 1 进程优先级等级一般分法 Activte process Visible Process Service process Background process Empty process 2 Service技巧 onStartCommand返回START_STICKY onDestroy中startself Service后台变前置,setForground(true) android:persistent = “true” 3 进程优先级号 ProcessList.java //Adjustmentusedincertainplaceswherewedon'tknowityet. //(Generallythisissomethingthatisgoingtobecached,butwe //don'tknowtheexactvalueinthecachedrangetoassignyet.) staticfinalintUNKNOWN_ADJ=16; //Thisisaprocessonlyhostingactivitiesthatarenotvisible, //soitcanbekilledwithoutanydisruption. staticfinalintCACHED_APP_MAX_ADJ=15; staticfinalintCACHED_APP_MIN_ADJ=9; //TheBlistofSERVICE_ADJ--thesearetheoldanddecrepit //servicesthataren'tasshinyandinterestingastheonesintheAlist. staticfinalintSERVICE_B_ADJ=8; //Thisistheprocessofthepreviousapplicationthattheuserwasin. //Thisprocessiskeptaboveotherthings,becauseitisverycommonto //switchbacktothepreviousapp.Thisisimportantbothforrecent //taskswitch(togglingbetweenthetwotoprecentapps)aswellasnormal //UIflowsuchasclickingonaURIinthee-mailapptoviewinthebrowser, //andthenpressingbacktoreturntoe-mail. staticfinalintPREVIOUS_APP_ADJ=7; //Thisisaprocessholdingthehomeapplication--wewanttotry //avoidingkillingit,evenifitwouldnormallybeinthebackground, //becausetheuserinteractswithitsomuch. staticfinalintHOME_APP_ADJ=6; //Thisisaprocessholdinganapplicationservice--killingitwillnot //havemuchofanimpactasfarastheuserisconcerned. staticfinalintSERVICE_ADJ=5; //Thisisaprocesswithaheavy-weightapplication.Itisinthe //background,butwewanttotrytoavoidkillingit.Valuesetin //system/rootdir/init.rconstartup. staticfinalintHEAVY_WEIGHT_APP_ADJ=4; //Thisisaprocesscurrentlyhostingabackupoperation.Killingit //isnotentirelyfatalbutisgenerallyabadidea. staticfinalintBACKUP_APP_ADJ=3; //Thisisaprocessonlyhostingcomponentsthatareperceptibletothe //user,andwereallywanttoavoidkillingthem,buttheyarenot //immediatelyvisible.Anexampleisbackgroundmusicplayback. staticfinalintPERCEPTIBLE_APP_ADJ=2; //Thisisaprocessonlyhostingactivitiesthatarevisibletothe //user,sowe'dprefertheydon'tdisappear. staticfinalintVISIBLE_APP_ADJ=1; //Thisistheprocessrunningthecurrentforegroundapp.We'dreally //rathernotkillit! staticfinalintFOREGROUND_APP_ADJ=0; //Thisisaprocessthatthesystemorapersistentprocesshasboundto, //andindicateditisimportant. staticfinalintPERSISTENT_SERVICE_ADJ=-11; //Thisisasystempersistentprocess,suchastelephony.Definitely //don'twanttokillit,butdoingsoisnotcompletelyfatal. staticfinalintPERSISTENT_PROC_ADJ=-12; //Thesystemprocessrunsatthedefaultadjustment. staticfinalintSYSTEM_ADJ=-16; //Specialcodefornativeprocessesthatarenotbeingmanagedbythesystem(so //don'thaveanoomadjassignedbythesystem). staticfinalintNATIVE_ADJ=-17; Android Low Memory Killer Android系统内存不足时,系统会杀掉一部分进程以释放空间,谁生谁死的这个生死大权就是由LMK所决定的,这就是Android系统中的Low Memory Killer,其基于Linux的OOM机制,其阈值定义如下面所示的lowmemorykiller文件中,当然也可以通过系统的init.rc实现自定义。 lowmemorykiller.c staticuint32_tlowmem_debug_level=1; staticintlowmem_adj[6]={ 0, 1, 6, 12, }; staticintlowmem_adj_size=4; staticintlowmem_minfree[6]={ 3*512,/*6MB*/ 2*1024,/*8MB*/ 4*1024,/*16MB*/ 16*1024,/*64MB*/ }; staticintlowmem_minfree_size=4; ① 在Low Memory Killer中通过进程的oom_adj与占用内存的大小决定要杀死的进程,oom_adj值越小越不容易被杀死。其中,lowmem_minfree是杀进程的时机,谁被杀,则取决于lowmem_adj,具体值得含义参考上面 Android进程优先级 所述. ② 在init.rc中定义了init进程(系统进程)的oom_adj为-16,其不可能会被杀死(init的PID是1),而前台进程是0(这里的前台进程是指用户正在使用的Activity所在的进程),用户按Home键回到桌面时的优先级是6,普通的Service的进程是8. init.rc #Setinitanditsforkedchildren'soom_adj. write/proc/1/oom_adj-16 关于Low Memory Killer的具体实现原理可参考Ref-2. 查看某个App的进程 步骤(手机与PC连接) adb shell ps | grep 进程名 cat /proc/pid/oom_adj //其中pid是上述grep得到的进程号 Linux AM命令 am命令:在Android系统中通过adb shell 启动某个Activity、Service、拨打电话、启动浏览器等操作Android的命令.其源码在Am.java中,在shell环境下执行am命令实际是启动一个线程执行Am.java中的主函数(main方法),am命令后跟的参数都会当做运行时参数传递到主函数中,主要实现在Am.java的run方法中。 拨打电话 命令:am start -a android.intent.action.CALL -d tel:电话号码 示例:am start -a android.intent.action.CALL -d tel:10086 打开一个网页 命令:am start -a android.intent.action.VIEW -d 网址 示例:am start -a android.intent.action.VIEW -d http://www.skyseraph.com 启动一个服务 命令:am startservice <服务名称> 示例:am startservice -n com.android.music/ com.android.music.MediaPlaybackService NotificationListenerService “A service that receives calls from the system when new notifications are posted or removed, or their ranking changed.” From Google 用来监听到通知的发送以及移除和排名位置变化,如果我们注册了这个服务,当系统任何一条通知到来或者被移除掉,我们都能通过这个service来监听到,甚至可以做一些管理工作。 Android账号和同步机制 属于Android中较偏冷的知识,具体参考 Ref 3 /4 /5 Android多进程 实现:android:process 好处:一个独立的进程可以充分利用自己的RAM预算,使其主进程拥有更多的空间处理资源。此外,操作系统对待运行在不同组件中的进程是不一样的。这意味着,当系统运行在低可用内存的条件时,并不是所有的进程都会被杀死 大坑:每一个进程将有自己的Dalvik VM实例,意味着你不能通过这些实例共享数据,至少不是传统意义上的。例如,静态字段在每个进程都有自己的值,而不是你倾向于相信的只有一个值。 更多详细请参考Ref 9 现有方法 网络连接保活方法 A. GCM B. 公共的第三方push通道(信鸽等) C. 自身跟服务器通过轮询,或者长连接 具体实现请参考 微信架构师杨干荣的”微信Android客户端后台保活经验分享” (Ref-1). 双service(通知栏) 提高进程优先级 思路:(API level > 18 ) 应用启动时启动一个假的Service(FakeService), startForeground(),传一个空的Notification 启动真正的Service(AlwaysLiveService),startForeground(),注意必须相同Notification ID FakeService stopForeground() 效果:通过adb查看,运行在后台的服务其进程号变成了1(优先级仅次于前台进程) 风险:Android系统前台service的一个漏洞,可能在6.0以上系统中修复 实现:核心代码如下 AlwaysLiveService 常驻内存服务 @Override publicintonStartCommand(Intentintent,intflags,intstartId){ startForeground(R.id.notify,newNotification()); startService(newIntent(this,FakeService.class)); returnsuper.onStartCommand(intent,flags,startId); } FakeService 临时服务 publicclassFakeServiceextendsService{ @Nullable @Override publicIBinderonBind(Intentintent){ returnnull; } @Override publicintonStartCommand(Intentintent,intflags,intstartId){ startForeground(R.id.notify,newNotification()); stopSelf(); returnsuper.onStartCommand(intent,flags,startId); } @Override publicvoidonDestroy(){ stopForeground(true); super.onDestroy(); } } Service及时拉起 AlarmReceiver, ConnectReceiver,BootReceiver等 Service设置(见上面基础部分) 通过监听系统广播,如开机,锁屏,亮屏等重新启动服务 通过alarm定时器,启动服务 守护进程/进程互拉 在分析360手机助手app时,发现其拥有N多个进程,一个进程kill后会被其它未kill的进程拉起,这也是一种思路吧,虽然有点流氓~ 守护进程一般有这样两种方式: 多个java进程守护互拉 底层C守护进程拉起App上层/java进程 Linux Am命令开启后台进程 一种底层实现让进程不被杀死的方法,在Android4.4以上可能有兼容性问题,具体参考Ref-7 NotificationListenerService通知 一种需要用户允许特定权限的系统拉起方式,4.3以上系统 前台浮窗 有朋友提出一种应用退出后启动一个不可交互的浮窗,个人觉得这种方法是无效的,读者有兴趣可以一试 新方法(AccountSync) 思路 利用Android系统提供的账号和同步机制实现 效果 通过adb查看,运行在后台的服务其进程号变成了1(优先级仅次于前台进程),能提高进程优先级,对比如下图 正常情况 采用AccountSyncAdapter方法后 进程被系统kill后,可以由syn拉起 风险 SyncAdapter时间进度不高,往往会因为手机处于休眠状态,而时间往后调整,同步间隔最低为1分钟 用户可以单独停止或者删除,有些手机账号默认是不同步的,需要手动开启 实现 (核心代码) 1 建立数据同步系统(ContentProvider) 通过一个ContentProvider用来作数据同步,由于并没有实际数据同步,所以此处就直接建立一个空的ContentProvider即可 publicclassXXAccountProviderextendsContentProvider{ publicstaticfinalStringAUTHORITY="包名.provider"; publicstaticfinalStringCONTENT_URI_BASE="content://"+AUTHORITY; publicstaticfinalStringTABLE_NAME="data"; publicstaticfinalUriCONTENT_URI=Uri.parse(CONTENT_URI_BASE+"/"+TABLE_NAME); @Override publicbooleanonCreate(){ returntrue; } @Nullable @Override publicCursorquery(Uriuri,String[]projection,Stringselection, String[]selectionArgs,StringsortOrder){ returnnull; } @Nullable @Override publicStringgetType(Uriuri){ returnnewString(); } @Nullable @Override publicUriinsert(Uriuri,ContentValuesvalues){ returnnull; } @Override publicintdelete(Uriuri,Stringselection,String[]selectionArgs){ return0; } @Override publicintupdate(Uriuri,ContentValuesvalues,Stringselection,String[]selectionArgs){ return0; } } 然后再Manifest中声明 <provider android:name="**.XXAccountProvider" android:authorities="@string/account_auth_provider" android:exported="false" android:syncable="true"/> 2 建立Sync系统 (SyncAdapter) 通过实现SyncAdapter这个系统服务后, 利用系统的定时器对程序数据ContentProvider进行更新,具体步骤为: 创建Sync服务 publicclassXXSyncServiceextendsService{ privatestaticfinalObjectsSyncAdapterLock=newObject(); privatestaticXXSyncAdaptersSyncAdapter=null; @Override publicvoidonCreate(){ synchronized(sSyncAdapterLock){ if(sSyncAdapter==null){ sSyncAdapter=newXXSyncAdapter(getApplicationContext(),true); } } } @Override publicIBinderonBind(Intentintent){ returnsSyncAdapter.getSyncAdapterBinder(); } staticclassXXSyncAdapterextendsAbstractThreadedSyncAdapter{ publicXXSyncAdapter(Contextcontext,booleanautoInitialize){ super(context,autoInitialize); } @Override publicvoidonPerformSync(Accountaccount,Bundleextras,Stringauthority,ContentProviderClientprovider,SyncResultsyncResult){ getContext().getContentResolver().notifyChange(XXAccountProvider.CONTENT_URI,null,false); } } } 声明Sync服务 <service android:name="**.XXSyncService" android:exported="true" android:process=":core"> <intent-filter> <action android:name="android.content.SyncAdapter"/> </intent-filter> <meta-data android:name="android.content.SyncAdapter" android:resource="@xml/sync_adapter"/> </service> 其中sync_adapter为: <sync-adapterxmlns:android="http://schemas.android.com/apk/res/android" android:accountType="@string/account_auth_type" android:allowParallelSyncs="false" android:contentAuthority="@string/account_auth_provide" android:isAlwaysSyncable="true" android:supportsUploading="false" android:userVisible="true"/> 参数说明: android:contentAuthority 指定要同步的ContentProvider在其AndroidManifest.xml文件中有个android:authorities属性。 android:accountType 表示进行同步的账号的类型。 android:userVisible 设置是否在“设置”中显示 android:supportsUploading 设置是否必须notifyChange通知才能同步 android:allowParallelSyncs 是否支持多账号同时同步 android:isAlwaysSyncable 设置所有账号的isSyncable为1 android:syncAdapterSettingsAction 指定一个可以设置同步的activity的Action。 账户调用Sync服务 首先配置好Account(第三步),然后再通过ContentProvider实现 手动更新 publicvoidtriggerRefresh(){ Bundleb=newBundle(); b.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL,true); b.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED,true); ContentResolver.requestSync( account, CONTENT_AUTHORITY, b); } 添加账号 Accountaccount=AccountService.GetAccount(); AccountManageraccountManager=(AccountManager)context.getSystemService(Context.ACCOUNT_SERVICE); accountManager.addAccountExplicitly(...) 同步周期设置 ContentResolver.setIsSyncable(account,CONTENT_AUTHORITY,1); ContentResolver.setSyncAutomatically(account,CONTENT_AUTHORITY,true); ContentResolver.addPeriodicSync(account,CONTENT_AUTHORITY,newBundle(),SYNC_FREQUENCY); 3 建立账号系统 (Account Authenticator) 通过建立Account账号,并关联SyncAdapter服务实现同步 接下文 本文作者:佚名 来源:51CTO

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

一种提高Android应用进程存活率新方法(下)

接上文 创建 Account服务 publicclassXXAuthServiceextendsService{ privateXXAuthenticatormAuthenticator; @Override publicvoidonCreate(){ mAuthenticator=newXXAuthenticator(this); } privateXXAuthenticatorgetAuthenticator(){ if(mAuthenticator==null) mAuthenticator=newXXAuthenticator(this); returnmAuthenticator; } @Override publicIBinderonBind(Intentintent){ returngetAuthenticator().getIBinder(); } classXXAuthenticatorextendsAbstractAccountAuthenticator{ privatefinalContextcontext; privateAccountManageraccountManager; publicXXAuthenticator(Contextcontext){ super(context); this.context=context; accountManager=AccountManager.get(context); } @Override publicBundleaddAccount(AccountAuthenticatorResponseresponse,StringaccountType,StringauthTokenType,String[]requiredFeatures,Bundleoptions) throwsNetworkErrorException{ //添加账号示例代码 finalBundlebundle=newBundle(); finalIntentintent=newIntent(context,AuthActivity.class); intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,response); bundle.putParcelable(AccountManager.KEY_INTENT,intent); returnbundle; } @Override publicBundlegetAuthToken(AccountAuthenticatorResponseresponse,Accountaccount,StringauthTokenType,Bundleoptions) throwsNetworkErrorException{ //认证示例代码 StringauthToken=accountManager.peekAuthToken(account,getString(R.string.account_token_type)); //ifnot,mightbeexpired,registeragain if(TextUtils.isEmpty(authToken)){ finalStringpassword=accountManager.getPassword(account); if(password!=null){ //getnewtoken authToken=account.name+password; } } //withoutpassword,needtosignagain finalBundlebundle=newBundle(); if(!TextUtils.isEmpty(authToken)){ bundle.putString(AccountManager.KEY_ACCOUNT_NAME,account.name); bundle.putString(AccountManager.KEY_ACCOUNT_TYPE,account.type); bundle.putString(AccountManager.KEY_AUTHTOKEN,authToken); returnbundle; } //noaccountdataatall,needtodoasign finalIntentintent=newIntent(context,AuthActivity.class); intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,response); intent.putExtra(AuthActivity.ARG_ACCOUNT_NAME,account.name); bundle.putParcelable(AccountManager.KEY_INTENT,intent); returnbundle; } @Override publicStringgetAuthTokenLabel(StringauthTokenType){ //thrownewUnsupportedOperationException(); returnnull; } @Override publicBundleeditProperties(AccountAuthenticatorResponseresponse,StringaccountType){ returnnull; } @Override publicBundleconfirmCredentials(AccountAuthenticatorResponseresponse,Accountaccount,Bundleoptions) throwsNetworkErrorException{ returnnull; } @Override publicBundleupdateCredentials(AccountAuthenticatorResponseresponse,Accountaccount,StringauthTokenType,Bundleoptions) throwsNetworkErrorException{ returnnull; } @Override publicBundlehasFeatures(AccountAuthenticatorResponseresponse,Accountaccount,String[]features) throwsNetworkErrorException{ returnnull; } } } 声明Account服务 <service android:name="**.XXAuthService" android:exported="true" android:process=":core"> <intent-filter> <action android:name="android.accounts.AccountAuthenticator"/> </intent-filter> <meta-data android:name="android.accounts.AccountAuthenticator" android:resource="@xml/authenticator"/> </service> 其中authenticator为: <?xmlversion="1.0"encoding="utf-8"?> <account-authenticatorxmlns:android="http://schemas.android.com/apk/res/android" android:accountType="@string/account_auth_type" android:icon="@drawable/icon" android:smallIcon="@drawable/icon" android:label="@string/app_name" /> 使用Account服务 同SyncAdapter,通过AccountManager使用 。申请Token主要是通过 AccountManager.getAuthToken)系列方法 。添加账号则通过 AccountManager.addAccount) 。查看是否存在账号通过 AccountManager.getAccountsByType) Refs 微信Android客户端后台保活经验分享 Android Low Memory Killer原理 stackOverflow 上介绍的双Service方法 Write your own Android Sync Adapter Write your own Android Authenticator Android developer android.accounts AccountManager AbstractAccountAuthenticator AccountAuthenticatorActivity Creating a Sync Adapter Android篇从底层实现让进程不被杀死(失效Closed) Android 4.3+ NotificationListenerService 的使用 Going multiprocess on Android 本文作者:佚名 来源:51CTO

资源下载

更多资源
Mario

Mario

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

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

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部分的功能。

用户登录
用户注册