-
Android内存优化(四)系统级别的内存回收策略优化--process reclaim
2018-10-08 23:25:29曾经反编译过某厂商的framework代码,结合厂商机器的表现,发现了进程内存管理的部分逻辑,记录如下: 之前一直怀疑某厂商的AMS.updateOomAdjLocked()方法中,添加了进程管理逻辑, 结果是进程管理的代码还没核实,...曾经反编译过某厂商的framework代码,结合厂商机器的表现,发现了进程内存管理的部分逻辑,记录如下:
之前一直怀疑某厂商的AMS.updateOomAdjLocked()方法中,添加了进程管理逻辑,
结果是进程管理的代码还没核实,倒是找到了运行时proc reclaim逻辑,
在反编译的AMS.updateOomAdjLocked()方法中,发现以下逻辑:try { if ((ActivityManagerDebugConfig.DEBUG_SWITCH) || ( ActivityManagerDebugConfig.DEBUG_OOM_ADJ)) { Slog.v(TAG_OOM_ADJ, "Trimming memory of " + localIndexOutOfBoundsException1.processName + " to " + i1); } SmartShrinker.reclaim(localIndexOutOfBoundsException1.pid, 4); localIndexOutOfBoundsException1.thread.scheduleTrimMemory(i1); } catch (RemoteException localRemoteException5)
我看了下SmartShrinker的实现,主体逻辑:
public static final void reclaim(int paramInt1, int paramInt2) { if (ENABLE) { ProcessList.callProcReclaim(paramInt1, paramInt2); Log.w("RMS.SmartShrinker", "SmartShrinker is runing in pid =" + paramInt1 + " reclaim mode = " + paramInt2); } }
再看下callProcReclaim方法:
public static final void callProcReclaim(int paramInt1, int paramInt2) { long l1 = SystemClock.elapsedRealtime(); ByteBuffer localByteBuffer = ByteBuffer.allocate(16); localByteBuffer.putInt(54); localByteBuffer.putInt(paramInt1); localByteBuffer.putInt(paramInt2); writeLmkd(localByteBuffer); long l2 = SystemClock.elapsedRealtime(); if (l2 - l1 > 250L) { Slog.w("ActivityManager", "SLOW call process reclaim: " + (l2 - l1)); } }
由此可见这个策略是进程级别的proc reclaim,
运行时的proc reclaim由属性ro.config.hw_smart_shrink控制,
boolean bool = SystemProperties.getBoolean(“ro.config.hw_smart_shrink”, false)
在高端机上没有开,此属性没有设置,而在中低端机上设置为true
[ro.config.hw_smart_shrink]: [true]运行时的proc reclaim时机?
全局搜了下,在AMS的两个接口中,updateOomAdjLocked和cleanUpRemovedTaskLocked
./com/android/server/am/ActivityManagerService.smali:12332: invoke-static {v13, v14}, Lcom/android/server/SmartShrinker;->reclaim(II)V
./com/android/server/am/ActivityManagerService.smali:115272: invoke-static {v6, v7}, Lcom/android/server/SmartShrinker;->reclaim(II)V
./com/android/server/am/ActivityManagerService.smali:115354: invoke-static {v2, v7}, Lcom/android/server/SmartShrinker;->reclaim(II)V
./com/android/server/am/ActivityManagerService.smali:121014: invoke-static {v5, v7}, Lcom/android/server/SmartShrinker;->reclaim(II)V
./com/android/server/pm/PackageManagerService$PackageHandler.smali:1605: invoke-static {v4, v10}, Lcom/android/server/SmartShrinker;->reclaim(II)V
./com/android/server/SystemServer.smali:1061: invoke-static {v2, v3}, Lcom/android/server/SmartShrinker;->reclaim(II)V
<1>ActivityManagerService.updateOomAdjLocked
在trim memory 操作时,对于重要性小于home的进程做process reclaim,基本都是不活跃的进程。
对应到代码位置:if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME && !app.killedByAm) { if (app.trimMemoryLevel < curLevel && app.thread != null) { try { if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, "Trimming memory of " + app.processName + " to " + curLevel); SmartShrinker.reclaim(app.pid, 4); app.thread.scheduleTrimMemory(curLevel); } catch (RemoteException e) { }
<2>ActivityManagerService.cleanUpRemovedTaskLocked
看下smali文件,尝试还原了下逻辑,并将代码对应上,这个地方应该是有些进程不杀,只做trim memory 操作和proc reclaim操作// Kill the running processes. for (int i = 0; i < procsToKill.size(); i++) { ProcessRecord pr = procsToKill.get(i); if (pr != null && pr.curAdj >= 900 && pr.info.flags & 0x1) != 0 && pr.info.hwFlags & 0x2000000) == 0 ) { Slog.d(TAG, " the process " + pr.processName + " adj >= " + 900); try{ SmartShrinker.reclaim(pr.pid, 4); pr.thread.scheduleTrimMemory(80); } catch (RemoteException localRemoteException) {} pr.trimMemoryLevel = 80; } else if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND && pr.curReceiver == null) { pr.kill("remove task", true); } else { // We delay killing processes that are not in the background or running a receiver. pr.waitingToKill = "remove task"; } }
<3>ActivityManagerService.trimServicesAfterBoot
原生代码上没有此代码,应该是厂商自己添加的接口,在ActivityManagerService.MainHandler的handleMessage()使用
反编译逻辑比较多,暂不贴出
<4>SystemServer.run
根据smali文件还原逻辑,跟代码对上,// Loop forever. Slog.i(TAG, "Entered the Android system server main thread loop."); SmartShrinker.reclaim(Process.myPid(),0x3) Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited");
<5>PackageManagerService$PackageHandler.doHandleMessage
根据smali文件还原逻辑,跟代码对上,在POST_INSTALL处理逻辑中// Add the args.info.getLocation for install exception statistics handlePackagePostInstall(childRes, grantPermissions, killApp, grantedPermissions, false, args.installerPackageName, args.observer, args.origin.getLocation()); } SmartShrinker.reclaim(Process.myPid(),3) // Log tracing if needed if (args.traceMethod != null) { Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod, args.traceCookie); }
从上面的逻辑中看,往SmartShrinker传参时,传的3或者4,在SmarShrinker的定义为:
public static final int RECLAIM_ALL_MODE = 2;
public static final int RECLAIM_ANON_MODE = 1;
public static final int RECLAIM_INACTIVE_MODE = 4;
public static final int RECLAIM_SOFT_MODE = 3;整体看,proc reclaim的时机有:
1:updateOomAdj 对于不活跃的重要性小于home的进程进程proc reclaim
2:cleanUpRemovedTaskLocked 清除task时,有些进程不杀掉,只做trim和proc reclaim(一键清理有很多App是杀不掉的,不知道和这个地方是否有关)
3:trimServicesAfterBoot 开机启动的时候,对service proc reclaim(看smali中,还有对zygote的proc reclaim,通过ro.config.reclaim_zygote控制)
4:system server启动后,loop之前做一次proc reclaim
5:PMS的POST_INSTALL 消息处理逻辑,应该是安装完成后做proc reclaim感觉这套已成体系,做的比较完善,开机的时候模块调用SmartShrinker进行进程的proc reclaim即可~
而且进程proc reclaim的内容分为all, anon,inactive,soft四种,分的更细一些,比如运行时,proc reclaim的是INACTIVE文件页,个人感觉比较合理 -
【redis】redis内存管理、淘汰机制、内存优化
2020-12-29 11:54:49内存优化 使用32位的redis 位级别和字级别的操作 尽可能使用散列表 配置redis 如果想要运行一个内存高效的 Redis 数据库,首先需要理解那些在 redis.conf 配置文件中所有内存相关的指令。r文章目录
配置redis
如果想要运行一个内存高效的 Redis 数据库,首先需要理解那些在 redis.conf 配置文件中所有内存相关的指令。redis.conf 文件为大多数指令提供了丰富的内联文档,使得一些复杂的内存优化选项易于理解、更改和测试。
传送门:redis.conf翻译与配置内存管理部分大多数 Redis 配置指令可以在运行时通过 CONFIG SET 命令进行设置。
最大内存限制
Redis使用 maxmemory 参数限制最大可用内存,默认关闭。
限制内存的目的主要 有:
用于缓存场景,当超出内存上限 maxmemory 时使用 LRU 等删除策略释放空间。 防止所用内存超过服务器物理内存。 12
maxmemory 限制的是Redis实际使用的内存量,也就是 used_memory统计项对应的内存。由于内存碎片率的存在,实际消耗的内存 可能会比maxmemory设置的更大,实际使用时要小心这部分内存溢出。redis.conf翻译与配置(内存碎片部分)
Redis默认无限使用服务器内存,为防止极端情况下导致系统内存耗 尽,建议所有的Redis进程都要配置maxmemory。 在保证物理内存可用的情况下,系统中所有Redis实例可以调整 maxmemory参数来达到自由伸缩内存的目的。
查看redis内存相关信息:INFO memory
当 memfragmentationratio > 1 时,说明有部分内存并没有用于数据存储,而是被内存碎片所消耗,如果该值很大,说明碎片率严重。当 memfragmentationratio < 1 时,这种情况一般出现在操作系统把 Redis 内存交换 (swap) 到硬盘导致,出现这种情况要格外关注,由于硬盘速度远远慢于内存,Redis 性能会变得很差,甚至僵死。
当 Redis 内存超出可以获得内存时,操作系统会进行 swap,将旧的页写入硬盘。从硬盘读写大概比从内存读写要慢5个数量级。used_memory 指标可以帮助判断 Redis 是否有被swap的风险或者它已经被swap。
建议要设置和内存一样大小的交换区,如果没有交换区,一旦 Redis 突然需要的内存大于当前操作系统可用内存时,Redis 会因为 out of memory 而被 Linix Kernel 的 OOM Killer 直接杀死。虽然当 Redis 的数据被换出 (swap out) 时,Redis的性能会变差,但是总比直接被杀死的好。:建议自:https://redis.io/topics/admin
内存都去哪儿了?还没好好使用,就爆了
1.自身内存:redis自身运行所消耗的内存,一般很小。2.对象内存:这是redis消耗内存最大的一块,存储着用户所有的数据。
3.缓冲内存:缓冲内存主要包括:客户端缓冲、复制积压缓冲区、AOF缓冲区。
客户端缓冲:是指客户端连接redis之后,输入或者输出数据的缓冲区,其中输出缓冲可以通过配置参数参数client-output-buffer-limit控制。
复制积压缓冲区:一个可重用的固定大小缓冲区用于实现部分复制功能,根据repl-backlog-size参数控制,默认1MB。对于复制积压缓冲区整个主节点只有一个,所有的从节点共享此缓冲区,因此可以设置较大的缓冲区空间,如100MB,这部分内存投入是有价值的,可以有效避免全量复制。
AOF缓冲区:这部分空间用于在Redis重写期间保存最近的写入命令,AOF缓冲区空间消耗用户无法控制,消耗的内存取决于AOF重写时间和写入命令量,这部分空间占用通常很小。4.内存碎片:当然,这是所有内存分配器无法避免的通病,但是可以优化。
如果对这方面有想法的话:走近STL – 空间配置器,STL背后的故事内存回收策略
Redis 回收内存大致有两个机制:一是删除到达过期时间的键值对象;二是当内存达到 maxmemory 时触发内存移除控制策略,强制删除选择出来的键值对象。
过期键值
Redis如何淘汰过期的keys
Redis keys过期有两种方式:被动和主动方式。
当一些客户端尝试访问它时,key会被发现并主动的过期。当然,这样是不够的,因为有些过期的keys,永远不会访问他们。 无论如何,这些keys应该过期,所以定时随机测试设置keys的过期时间。所有这些过期的keys将会从密钥空间删除。
具体就是Redis每秒10次做的事情:测试随机的20个keys进行相关过期检测。 删除所有已经过期的keys。 如果有多于25%的keys过期,重复步奏1. 123
为了获得正确的行为而不牺牲一致性,当一个key过期,DEL将会随着AOF文字一起合成到所有附加的slaves。在master实例中,这种方法是集中的,并且不存在一致性错误的机会。
然而,当slaves连接到master时,不会独立过期keys(会等到master执行DEL命令),他们任然会在数据集里面存在,所以当slave当选为master时淘汰keys会独立执行,然后成为master。
内存移除控制策略
8个解决方方案
当maxmemory限制达到的时候Redis会使用的行为由 Redis的maxmemory-policy配置指令来进行配置。
在redis.conf中提出了8个解决方法。
volatile-lru ->退出使用近似的LRU,仅使用设置了过期值的键。 allkeys-lru ->使用近似的LRU驱逐任何密钥。 volatile-lfu ->使用近似的LFU逐出,仅使用具有过期集的键。 allkeys-lfu ->使用近似的LFU驱逐任何密钥。 volatile-random ->删除一个具有过期设置的随机键。 allkeys-random ->删除一个随机键,任意键。 volatile-ttl ->删除最近过期时间的密钥(较小的TTL) noeviction ->不驱逐任何东西,只是在写操作时返回一个错误。 12345678
LRU表示最近最少使用
LFU表示使用频率最低
LRU、LFU和volatile-ttl都是使用近似随机算法实现的。注意:使用上述任何策略,当没有合适的键用于驱逐时,Redis会在写操作时返回一个错误。
一般的经验规则:
使用allkeys-lru策略:当你希望你的请求符合一个幂定律分布,也就是说,你希望部分的子集元素将比其它其它元素被访问的更多。如果你不确定选择什么,这是个很好的选择。. 使用allkeys-random:如果你是循环访问,所有的键被连续的扫描,或者你希望请求分布正常(所有元素被访问的概率都差不多)。 使用volatile-ttl:如果你想要通过创建缓存对象时设置TTL值,来决定哪些对象应该被过期。 123
allkeys-lru 和 volatile-random策略对于当你想要单一的实例实现缓存及持久化一些键时很有用。不过一般运行两个实例是解决这个问题的更好方法。
为了键设置过期时间也是需要消耗内存的,所以使用allkeys-lru这种策略更加高效。回收进程如何工作
理解回收进程如何工作是非常重要的:
一个客户端运行了新的命令,添加了新的数据。 Redis检查内存使用情况,如果大于maxmemory的限制, 则根据设定好的策略进行回收。 一个新的命令被执行,等等。 所以我们不断地穿越内存限制的边界,通过不断达到边界然后不断地回收回到边界以下。 1234
近似LRU算法
Redis的LRU算法并非完整的实现。
Redis为什么不使用真实的LRU实现是因为这需要太多的内存。内存优化
使用32位的redis
使用32位的redis,对于每一个key,将使用更少的内存,因为32位程序,指针占用的字节数更少。但是32的redis整个实例使用的内存将被限制在4G以下。
使用make 32bit命令编译生成32位的redis。RDB和AOF文件是不区分32位和64位的(包括字节顺序),所以你可以使用64位的reidis恢复32位的RDB备份文件,相反亦然。位级别和字级别的操作
Redis 2.2引入了位级别和字级别的操作: GETRANGE, SETRANGE, GETBIT 和 SETBIT.使用这些命令。
对位操作不熟的话,可以看一下这两篇:
位运算 - 初见
位图 - 海量数据处理尽可能使用散列表
小散列表(是说散列表里面存储的数少)使用的内存非常小,所以你应该尽可能的将你的数据模型抽象到一个散列表里面。
-
提交订单性能优化系列之003-测试阿里巴巴的druid数据源
2018-09-14 20:52:38而druid数据源是一个工业级别的产品,它的内部做了大量的优化(比如多线程控制、性能监控等),这些优化的代码在运行的时候都是需要花时间的,因此相对就慢了一些。 003版本更新说明 pom.xml...概括总结
使用druid数据源之后,相对于第002版自己随手写的数据库,性能反而下降了8.49%。原因在于,002版是“随手”写的,因此功能非常简陋,要什么没什么,只能从内存中获取连接,因此很快。而druid数据源是一个工业级别的产品,它的内部做了大量的优化(比如多线程控制、性能监控等),这些优化的代码在运行的时候都是需要花时间的,因此相对就慢了一些。
003版本更新说明
pom.xml文件中引入了新的jar包:
<!-- 阿里的druid数据库连接工具 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.10</version> </dependency>
它提供了一般的数据库连接池工具都具备的功能,比如设置初始化连接数、最大连接数、最小空闲连接数等。但是它最大的卖点是它优秀的监控功能:哪些SQL执行次数最多?哪些SQL执行时间最长?等等之类的问题,它都帮你记录了。可以参考这篇文章:Druid Monitor监控JavaSE和JavaWeb
003版本中,修改了“JdbcUtil003.java”类,提供了一个
setDataSource
方法,以方便以后修改成其他的数据库连接池:/** 设置数据库源 */ public static void setDataSource(DataSource dataSourceOut) { dataSource = dataSourceOut; }
这个版本也做了一些其他的小修改,在这里就不列举。
测试结果
三个版本平均提交一个订单的耗时情况如下:
001版本耗时(ms) 002版本耗时(ms) 003版本耗时(ms) 183 106 115
002版本相对于001版本性能提升了: (183 - 106) / 183 * 100% = 42.07%003版本相对于001版本性能提升了: (183 - 115) / 183 * 100% = 37.15%
003版本相对于002版本性能下降了: (115 - 106) / 106 * 100% = 8.49%
【备注】:不同的机器上的测试结果会不一样,以上测试结果仅供参考。
“最好的”数据库连接池
druid的自我介绍是这样的:
“最好的”这三个字还真是自信啊,反正其他的数据库连接池都没说过这种话~
衷心希望它能越做越好,毕竟我们公司是一直都在用它。
源码
003版本的github源码在这里,如果不知道怎样运行项目,请参考这里
(转载本站文章请注明出处二胡1999 的个人技术博客www.erhu1999.com ,请勿用于任何商业用途)
-
tomcat 内存溢出_你知道tomcat运行模式中BIO、NIO和ARP之间的区别吗?
2020-12-15 18:32:46简述及配置运行模式1、bio:没经过任何优化和处理,几百并发性能极低下。配置server.xml2、nio:利用java的异步io技术,no blocking IO技术.配置server.xml3、apr模式安装最困难,操作系统级别的控制,但也是在To...概述
Tomcat8.0起已经默认nio模式,不需要做修改,BIO模式也已经抛弃了,今天主要介绍下tomcat的三种运行模式:BIO、NIO、ARP。
简述及配置运行模式
1、bio:没经过任何优化和处理,几百并发性能极低下。
配置server.xml
2、nio:利用java的异步io技术,no blocking IO技术.
配置server.xml
3、apr模式
安装最困难,操作系统级别的控制,但也是在Tomcat上运行高并发应用的首选模式。
配置apr模式之后还需要安装 apr 、 apr-utils 、tomcat-native包
(1)apr 安装
# tar zxf apr-1.5.2.tar.gz -C /usr/local/src/# cd /usr/local/src/apr-1.5.2/# ./configure --prefix=/usr/local/apr && make && make install
(2)apr-utils 安装
# tar zxf apr-util-1.5.4.tar.gz -C /usr/local/src/# cd /usr/local/src/apr-util-1.5.4/# ./configure --with-apr=/usr/local/apr/ --prefix=/usr/local/apr-utils && make && make install
(3)tomcat-native安装
# cd /usr/local/apache-tomcat-7.0.65/bin/# tar zxf tomcat-native.tar.gz# cd tomcat-native-1.1.33-src/jni/native# ./configure --with-apr=/usr/local/apr --with-java-home=/usr/local/java/ && make && make install
(4)配置APR环境变量
# vim /etc/profile新增配置以下配置export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/apr/lib使配置生效# source /etc/profile
BIO、NIO、AIO适用场景分析:
BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。
NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。
AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。
这三种模式的不同之处如下:
- BIO:
一个线程处理一个请求。缺点:并发量高时,线程数较多,浪费资源。
Tomcat7或以下,在Linux系统中默认使用这种方式。
- NIO:
利用Java的异步IO处理,可以通过少量的线程处理大量的请求。
Tomcat8在Linux系统中默认使用这种方式。
- APR:
即Apache Portable Runtime,从操作系统层面解决io阻塞问题。
Tomcat7或Tomcat8在Win7或以上的系统中启动默认使用这种方式。
官方对这三种的区别的详细说明:
Tomcat启动的时候,可以通过log看到Connector使用的是哪一种运行模式:
- Starting ProtocolHandler ["http-bio-8080"]
- Starting ProtocolHandler ["http-nio-8080"]
- Starting ProtocolHandler ["http-apr-8080"]
个人觉得在 tomcat bio、nio、apr 模式中,每种都会有各自适用的场合,也不能说哪个好那个不好,就像 tomcat 内存方面的配置,如果内存设置的过大,gc 垃圾回收机制就会变慢;如果内存设置的过小,tomcat又会出现内存溢出的情况,所以设置在一个合适的范围很重要,不仅不会出错,并且gc回收频繁使性能达到一个最优的结果。当然,这也需要根据不同的场合进行不同的测试才能产生最优的结果!
后面会分享更多关于devops和DBA方面的内容,感兴趣的朋友可以关注下!!
-
tomcat内存溢出解决方案_详解Tomcat三种运行模式(BIO, NIO, APR)的比较和场景分析...
2020-11-24 07:43:08简述及配置运行模式1、bio:没经过任何优化和处理,几百并发性能极低下。配置server.xml2、nio:利用java的异步io技术,no blocking IO技术.配置server.xml3、apr模式安装最困难,操作系统级别的控制,但也是在To... -
最近升级了一下小老婆(8核 2x8G DDR3 128G SSD)
2019-08-04 03:47:24晒图(笔者的硬件知识属于小白级别, 且看且参考吧): 另外优化一下休眠&虚拟内存功能节省SSD空间: 1. 台式机, 休眠功能基本没必要, 果断关掉 C:\Windows\system32>powercfg /H OFF 2.虚拟... -
Keil 仿真时变量“not in scope
2020-08-13 16:25:10问题:在调试程序的时候,函数返回值赋值给变量时...编译器优化级别高的时候,编译器为了优化,可能并没有按照我们想要执行的代码汇编。 解决:降低Keil的编译优化选项,如下图所示,优化等级改为0(默认为3)。 ... -
Keil调试局部变量显示"not in scope"的问题解决
2019-12-14 13:44:42今天在调试程序的时候,发现函数返回值赋值给...编译器优化级别高的时候,编译器为了优化,可能并没有按照我们想要执行的代码汇编。 解决方法:降低Keil的编译优化选项,如下图所示,优化等级改为0(默认为3)。 ... -
smarty的配置使用
2016-01-19 16:39:45smarty是 一个老牌Php模板引擎,作用是程序和美工分离(还没遇到会用smarty的 美工,还是自己整合),缓存技术...而memcache是内存对象缓存系统,与前两种比不是文件级别的缓存,而是内存级别的缓存。 配置: 1、在 -
smarty的配置实用
2016-05-09 12:41:00smarty是一个老牌Php模板引擎,作用是程序和美工分离(还没遇到会用smarty的 美工,还是自己整合),缓存...而memcache是内存对象缓存系统,与前两种比不是文件级别的缓存,而是内存级别的缓存。配置:1、在smarty官... -
做了一个小时的面试题(没有过 希望大家帮忙答下 虽然很幼稚 毕竟每个人都是这么过来的吗 感激了!...
2010-04-16 11:10:58垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有 使用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。 回收... -
iframe覆盖内部的某一部分_某高性能のB树索引
2021-01-18 15:52:35近期在做项目的时候遇到了千万级别的表关联查询,发现加索引和没加索引的区别真的很大。于是今天我们就来研究一下数据库的索引吧。众所周知使用索引可以将存储在数据库中的数据以某种数据结构的形式存储,使用索引会... -
Windows系统蓝屏机制
2021-01-17 14:07:29通常程序运行在Ring3级别, 当程序出现无法纠正的错误时, 该进程就会崩溃, 比如跑一个很大的工程, 或优化不好的游戏可能出现的进程崩溃. 而如果无法纠正的错误发生在系统内核, 这时windows系统就会所谓蓝屏. 通常是除... -
某高性能のB树索引
2021-02-17 23:37:33近期在做项目的时候遇到了千万级别的表关联查询,发现加索引和没加索引的区别真的很大。于是今天我们就来研究一下数据库的索引吧。 众所周知使用索引可以将存储在数据库中的数据以某种数据结构的形式存储,使用... -
内存泄漏优化;线程优化;Bitmap优化;网络优化;懒加载优化,启动页优化;静态变量优化;电量性能优化;view控件异常销毁保存重要信息优化;去除淡黄色警告优化;使用注解替代枚举优化;glide加速优化;多渠道打包...
-
multiCCL_f
2010-10-19 15:49:46(内存定位就没关系了) 记录文件格式: 只要注意以下几个字段和键值就可以了: [CharactorCodz] ;特征码总数 CharactorTotal= ;特征码的记录格式是 H_起始偏移_结束偏移_长度_…… ;一般只要注意 起始偏移 ... -
注 : 没链接的是还没写 Java基础核心串讲 计算机操作系统与Linux Java基础面试16问 52图初探Linux通用知识 大厂面试Linux就这5个问题 学习linux命令,看这篇2w多字的命令详解就够了 带宽、延时、吞吐率、PPS 这些...
-
phpfox网络社交程序 v2.0.7 全功能版.rar
2019-07-09 16:48:58您无需去接受专业的计算机培训就可以DIY您的社交网站,包括用户组级别的设置、会员自由添加付费广告和赞助项目等等都能让您的网站自由快速运转。 手机上网功能 通过手机上网功能,让您随时随地浏览和更新您的最新... -
phpFox 社交程序 v2.1.0.rar
2019-07-09 16:48:57无需专业知识 您无需去接受专业的计算机培训就可以DIY您的社交网站,包括用户组级别的设置、会员自由添加付费广告和赞助项目等等都能让您的网站自由快速运转。 手机上网功能 通过手机上网功能,让您随时随地浏览和... -
phpFox社交程序 v2.1.0.zip
2019-07-08 00:00:31您无需去接受专业的计算机培训就可以DIY您的社交网站,包括用户组级别的设置、会员自由添加付费广告和赞助项目等等都能让您的网站自由快速运转。 手机上网功能 通过手机上网功能,让您随时随地浏览和更新您的最新... -
Process Lasso pro v3.6专业中文单文件版
2009-06-11 13:30:25Processlasso 是一款独特的调试级别的系统优化工具,主要功能是动态调整各个进程的优先级并设为合理的优先级类以实现为系统减负的目的,此项特性被 ProcessLasso定义为过载抑制out-of-controlrestraint,可有效避免... -
虽然这样做可以节约内存,但当应用复杂后,造成了状态不可控,是很大的隐患,节约的内存优点变得得不偿失。 Immutable则不一样,相应的: foo = Immutable.Map({ a: 1 }); bar = foo.set('a', 2); foo.get('a') // 1...
-
数据库事务特性与隔离级别详解 SQL优化详解 基于代理的数据库分库分表框架 Mycat实践 其他 UML大科普:一文梳理清 14种 UML图 工具和软件 【置顶1】熬10天夜,肝出了这个PDF版「软件安装手册」 【置顶2】再...
-
3.5.3 给40亿个不重复的unsigned int的整数,没排过序的,然后再给几个数,如何快速判断这几个数是否在那40亿个数当中? 3.5.4 在一个文件中有10G个整数,乱序排列,要求找出中位数。内存限制为2G。 3.5.5 时分秒针...
-
比特币:一个点对点的电子现金系统
-
scrapy_settings.py
-
五金机械工具箱电商淘宝详情页设计模板.zip
-
工程制图 AutoCAD 2012 从二维到三维
-
PPT大神之路高清教程
-
前端学习第七天
-
MaxScale 实现 MySQL 读写分离与负载均衡
-
FTP 文件传输服务
-
MySQL 多实例安装 及配置主从复制实验环境
-
【Python-随到随学】FLask第二周
-
TypeError: Class advice impossible in Python3. Use the @Implementer class decorator instead.
-
jquery使用serialize()出现中文乱码怎么办
-
猫眼谐振腔在全外腔长氦氖激光器中的应用
-
使用vue搭建微信H5公众号项目
-
一个简单的PHP在线书签系统
-
【布道者】Linux极速入门
-
智能停车场云平台(附vue+SpringBoot前后端项目源码)
-
Galera 高可用 MySQL 集群(PXC v5.6 + Ngin
-
C++代码规范和Doxygen根据注释自动生成手册
-
实现 MySQL 读写分离的利器 mysql-proxy