冲击手机应用榜单Top3,高手都做了这些

2023-10-27

作者:舒大飞

博客地址:https://juejin.im/post/5b1b5e29f265da6e01174b84

由于项目里之前线上版本出现过一定比例的OOM,虽然比例并不大,但是还是暴露了一定的问题,所以打算对我们App分为几个步骤进行内存分析和优化,当然内存的优化是个长期的过程,不是一两个版本的事,每个版本都需要收集线上内存数据进行监控以及分析。

版本迭代过程中,内存增长过快,不仅会导致一定概率的OOM,运行时若出现内存抖动,导致频繁GC,则会对App的流畅度以及用户体验造成很大影响。

本文主要会根据实际项目中优化步骤分为以下几部分:

  • Android内存分析基础

  • 内存泄漏

  • 静态内存分析优化

  • 运行时内存分析优化

  • 监控

1.Android内存分析基础

这部分主要先介绍一些进行内存分析的基础方法以及工具,对这部分比较熟悉的同学可以先跳过哈。

一.App的内存使用情况概览

每个App进程可以分配到的最大内存是有限的,当然不同手机每个App进程可以分配到的最大内存有可能不一样,可以通过以下命令进行查看:

//dvm最大可用内存:
adb shell getprop | grep dalvik.vm.heapsize
//单个程序限制最大可用内存:
adb shell getprop|grep heapgrowthlimit

超过单个程序限制最大内存则OOM,如果设置了开启largeHeap,则可提高到dvm最大内存才OOM。

我们可以输出我们App的内存使用情况概览:

adb shell dumpsys meminfo 包名

我们就可以看到:

  • Pss: 该进程独占的内存+与其他进程共享的内存(按比例分配,比如与其他3个进程共享9K内存,则这部分为3K)

  • Privete Dirty:该进程独享内存

  • Heap Size:分配的内存

  • Heap Alloc:已使用的内存

  • Heap Free:空闲内存

二、Android Profiler

AndroidStduio3.0后Android Profiler变得比之前更强大,内存分析页变得更加直观更加方便,下面是截图:

  • 进程占用总内存

  • javaHeap:这部分内存大小是有限制的,溢出则会OOM,这部分内存也是我们分析优化的重点

  • NativeHeap:native层的 so 中调用malloc或new创建的内存,对于单个进程来说大小没有限制,所以可以利用在native层分配内存来缓解javaHeap的压力(比如2.3.3之前Android Bitmap的内存分配就是在native层,之后移到javaHeap, 8.0又回到native)

  • Graphics:这部分一般游戏app中用的较多,OpenGL和SurfaceFlinger相关的内存,若没有直接调用到OpenGL,则一般不会涉及到这块内存

  • Stack:栈,了解jvm内存模型的应该都知道

  • Code: 代码,主要是dex以及so等占用的内存

  • Others:就是others啦

所以我们可以看到事实上我们可以优化的点有:JavaHeap、NativeHeap、Stack、Code所占用的内存

三、强大的MAT

MAT是做比较细致的内存分析的利器了,功能十分强大,其中的:

  • Hisogram:Lists number of instances per class

  • Dominator Tree:List the biggest objects and what they keep alive.

可以非常方便的排序查看当前内存中最占内存的class或者实体对象,而且有一条非常清晰的引用链来查看该对象的持有者,这对内存的分析以及内存泄漏的分析都是非常友好的。

同时MAT支持compare对比功能,将两个.hprof文件导入,都Add to Compare Basket之后即可进行对比,这对于对比某个页面相较与前一页面的内存增量来说是非常有意义的。

有一点比较不友好的是,MAT需要标准的.hprof文件,所以在AndroidStduio的Profiler中GC后dump出的内存快照还要自己手动利用android sdk platform-tools下的hprof-conv进行转换一下才能被MAT打开。

内存泄漏

根据以往经验,其实做内存优化最先要搞定的应该是内存中的大头,这类大头对内存的占用很大,也是内存问题的主要祸首,相对来说比较容易定位问题,且优化后效果也非常明显,性价比非常高。

事实上很多优化都是这样,比如减包大小的优化,也是要先分析出主要大头祸首,比如可能你的包里包含了一张3M大小的无用图片,如果你没找到这种祸首,可能你做了大量的工作去想办法减少无用代码等,最终可能只有几百K的收益。

相对内存来说,这个大头就是:

  • 内存泄漏

  • 图片

所以首先你要确保你的应用里没有存在内存泄漏,然后再去做其他的内存优化。

内存泄漏检测

现在内存泄漏的检测已经变得非常简便了,使用App后在Android Profiler中先触发GC然后dump内存快照,之后点击按package分类,就可以迅速查看到你的App目前在内存中残留的class,点击class即可在右边查看到对应的实例以及引用对象。

当然你也可以在debug下集成LeakCanary做内存泄漏监控警告

排除内存泄漏后,图片就是另一个占用内存大头的对象了。

图片

对于图片来说一个是颜色模式,检查一下项目里的图片的颜色模式,是否可以降低,比如从RGB_8888降到RGB_565,则每张图片可以节省1/2的内存,如果没有使用到透明通道等的话基本上肉眼看不出差别。

还有一个是降低图片的大小,可能你的ImageView只有你图片的一半大,则这部分内存就大大浪费了,我们项目服务端会根据前端的参数做动态切图。

前端也可以通过降低采样率(inSampleSize)来达到降低图片占用内存大小的目的,但是这个采样率InSampleSize只能是整数(甚至只能是2的次方),如果inSampleSize=2,则最终内存占用就会是原来的1/4,适用于图片过大很多的情况,对于只是想做小幅度压缩的话,基本没用。

ok,接下来开始做具体的内存分析与稍微细致一点的内存优化。

静态内存分析优化

这边说的静态内存指的是在伴随着App的整个生命周期一直存在的那部分内存,也就是打底的,具体获取这部分内存快照的方式是: 打开App开始重度使用App,基本打开每一个主要页面主要功能,然后回到首页,进开发者选项打开"不保留后台活动",然后将我们的app退到后台。最后GC,dump出内存快照。 

下面是我们app dump出的内存快照,进行分析后制图如下:

通过对静态内存数据的分析,主要发现了以下几个问题:

问题1: App首页的主图有两张(一张是保底图,一张是动态加载的图),都比较大,而且动态加载的图回来后,保底图并没有及时被释放

优化:首先是对首页的主图进行颜色通道的改变以及压缩,可以大大降低这两张图所占的内存,然后在动态加载图回来后及时释放掉保底图 -5M

问题2: 首页底部的轮播背景图占用内存1.6M,且在图片加载回来后,背景图一直没有置空

优化:首先一般来说对背景图的质量并没有很高的要求,所以这张背景图是可以被成倍压缩的,并且在图片加载回来后,背景图要及时的释放掉。同时首页的多张轮播图以及其他图片都可以进行颜色模式的改变以及质量压缩。 -1.6M -4M

问题3: 项目会在App启动时拉一个接口获取一些实验配置,放进单例,在内存分析时发现,这些实验配置竟然接近1M

优化:排查后发现,接口拉的是整个公司所有部门的实验配置,上千个,这也给遍历拿一个实验配置带来一定的性能损耗,推动接口去改进,只获取当前部门业务需要的实验配置,可节省内存90%以上 -700K

问题4: 发现几个lottie动画一直没有被回收,并且同一个lottie动画会有几个不同的实例存在,总共占用内存450K

优化:首先要确定几个lottie动画为什么在页面退出后没有被回收,并且同一个动画有几个不同的实例,很容易就联想到内存泄漏,由于页面没有被销毁,所以导致几个lottie动画也没有被回收,排查下来是项目里的RN页面存在内存泄漏,解决后大概可以节省3-5M内存

问题5: SharePreference在内存里占用了700K的内存

优化:由于SP中的东西是会一次性加载到内存里并且保存为静态的,直到App进程结束才会被销毁,所以SP中千万别放大的对象,别图一时方便把对象序列化成json后保存到SP里,优化点就是把已经保存在SP中的一些较大的json字符串或者对象迁移到文件或者数据库缓存。 -400K

问题6: 埋点数据

优化:产品或者运营为了统计数据会在每个版本不断的增加新埋点,但是也需要定期去清理掉一些过时的不需要的埋点,来适当优化内存以及CPU的压力。

问题7: 还有就是一些App里的单例以及一些静态缓存

优化:整个看下来在我们项目中这部分占整体的静态内存其实较小,综合考虑内存情况以及使用的高效性可以进行一定程度的优化,不过这部分内存在App内存紧张时可以选择清理掉他们

我们可以选择在App退到后台后内存紧张即将被Kill掉时选择释放掉一些内存,如图片的缓存,静态缓存等来自保,具体做法是在Activity中重写onTrimMemory()方法(4.0之前是onLowMemory()),在这里面来做内存的释放。

静态内存优化:约15M

运行时内存分析优化

接下来做一下每个页面的运行时内存分析优化,这一部分就是随着App运行过程增长以及回收的内存,这部分工作十分繁琐,需要耐得住寂寞啊。

分析和优化运行时内存主要是通过以下两个核心方式:

  • 从首页开始用脚本dump出每个页面的内存快照文件,然后利用MAT的对比功能,找出每个页面相对于上个页面内存里主要增加了哪些东西,做针对性优化

  • 利用Android Profiler实时观察进入每个页面后的内存变化情况,对产生的内存较大波峰做分析

首先介绍一下我们App中我们产线的主要核心页面流程:搜索页-->列表页-->详情页-->信息页-->支付,这里重点对列表页和详情页做运行时内存分析优化。

(1)列表页内存优化

下面是列表页的内存快照与搜索页的对比:

可以看到,绝大部分的内存增加还是图片,当然还有一些静态缓存:

问题1:列表item被回收时还持有图片的引用

优化:应该在item被回收不可见时释放掉对图片的引用,这里注意RecyclerView与ListView的区别,如果是ListView,因为每次item被回收后再次利用都会重新绑定数据,只需在ImageView onDetchFromWindow的时候释放掉图片引用即可。

而对于RecyclerView来说,因为被回收不可见时第一选择是放进mCacheView中,而这里面的item被复用时并不会执行bindViewHolder来重新绑定数据,只有被回收进mRecyclePool中后拿出来复用才会重新绑定数据,所以如果是RecyclerView,我们释放图片引用的时机应该是item被回收进RecyclePool的时候,只要重写Adapter中的onViewRecycled方法即可:

@Override
public void onViewRecycled(@Nullable VH holder) {
    super.onViewRecycled(holder);
 if (holder != null) {
        //做释放图片引用的操作
 }
}

问题2:图片大小有优化空间

优化:这个因为我司在服务端会对图片进行动态切图,所以最简单的方法就是根据实际情况来改变动态切图的大小达到节省内存的作用,当然如果从服务端请求回来的图片实在大(一般不要比装载的ImageView要大),前端就可以采用降低采样率的方式来进行压缩,当然这个上面说了采样率(inSampleSize)只支持2的次方,所以对图片占用内存大小的压缩是非常大的,如果你只是想小幅度的压缩,基本上这个是没用的。

问题3:对Glide图片框架使用的思考

Glide是使用最普遍的图片加载框架,它帮我们做了大部分内存管理方面的事情,实际上它还支持做的更好。

优化:配置好 TrimMemory 和 LowMemory,主要用到 Glide 的 trimMemory() 和 cleanMemroy() 方法

  • 在 lowMemory 的时候,调用 Glide.cleanMemroy() 清理掉所有的内存缓存。

  • 在 App 被置换到后台的时候,调用 Glide.cleanMemroy() 清理掉所有的内存缓存。

  • 在其它情况的 onTrimMemroy() 回调中,直接调用 Glide.trimMemory() 方法来交给 Glide 处理内存情况。

(2)详情页的内存分析优化

可以看看刚进入详情页后会有一个明显的波峰,通过点击Adnroid Profiler上的红色圆点来记录查看这段波峰里的内存分配。

首先详情页依然有大量的图片,所以对于图片的大小以及复用上的优化上面已经说了,这里就不重复说了。

问题1:在内存里发现两个极少概率出现的empty view,占用了接近2M的内存

优化:用ViewStub对empty view做了懒加载,对于这些没有马上用到的资源要做延迟加载,还有很多大概率不会出现的View更加要做懒加载。 -2M

问题2:发现详情页的轮播大图的Viewpager用的Adapter是FragmentPagerAdapter,导致了所有的page都会被保存,当图片页数多的时候,往后翻内存会不断上升。

优化:这种页数多的ViewPager使用FragmentStatePagerAdapter来替代,它只会保留前后pager,在页数多的时候可以 节省大量内存。

问题3:对于一些实在大的图并且复用频率并不高的大图只采用文件缓存就行了,不做内存缓存。

问题4:我们项目在debug下会打印网络请求的reqeust和response,并且会用String.subString()对较长的response json进行截取

优化:本身subString()就比较耗内存,所以在response较大的时候就会申请大量的内存,好在这种情况只会在debug下发生,但是依然需要改进这种打印。

监控

内存的分析优化并不是一两个版本的事,而是一个必须每个版本持续进行的工作,这需要一套完善的线上用户内存使用情况监测系统来进行数据上传、数据分析、数据整理、数据对比,方便我们明确的了解每个版本线上App内存的具体情况。公司的一套性能监控平台,可以在这方面给我们App开发人员提供很直观的监控数据和版本迭代对比。

通过上面我们项目的内存分析,可以发现图片绝对是内存中的一块大头,所以对于图片的使用监控就显得尤为重要,我们自定义了一个简单的可以监控加载的图片是否过大的ImageView,可以在debug阶段发出警告,方便开发人员及早发现过大的图片。

当然要做的工作还有很多,比如当我们发现占用内存过高时,可以尝试来释放一些静态的缓存,一次来缓存内存的压力。

总结

这个版本利用了点时间对项目的内存占用做了以上分析以及优化,还需要做的还有很多,之后的版本会继续跟进,总得来说做内存分析和优化还是比较辛苦的,特别是各种内存快照的分析以及对代码问题的排查,当然时间有限,可能很多地方说的可能也有疏漏或者错误,纸上得来终觉浅,绝知此事要躬行,对于性能优化特别内存优化这一块,实践远比理论得到的要多。

目前项目里关于流畅度以及耗电量还没发现太大的问题,因为每个版本或多或少都会做一些优化,线上也有数据监测,之后还是想整理一下关于卡顿流程度的分析优化以及耗电量的分析优化实践。

近期文章:

今日问题:

内存优化,你有什么心得或者遇到什么问题?

留言格式:

打卡 天,答:xxx。

参与打卡活动:

 戳我看详情 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

冲击手机应用榜单Top3,高手都做了这些 的相关文章

  • 编译原理——词法分析器

    1 概述 设计 编制并调试一个简单的C语言词法分析程序 掌握利用状态转换图设计词法分析器的基本方法 利用该词法分析器完成对源程序字符串的词法分析 通过对该词法分析器的设计 加深对词法分析原理 状态转换图等编译原理知识的理解 2 使用的基本概
  • 最新bilibili怎么下载视频

    bilibili作为最火的二次元网站 很多人想下载下来 却不知道怎么下手 今天小编就来818怎么下载bilibili的视频 1 我们拿这案例来参考 https www bilibili com video av40672186 from s
  • d3碰撞源码分析

    技术 d3 d3 force d3 geom quadtree d3 geom quadtree 四叉树的应用 图像处理 空间数据索引 2D中的快速碰撞检测 存储稀疏数据等 游戏编程 上图中的数据就是普通的点 点与点之间没有关系 此函数在构
  • TOJ--3100:Getting Gold (DFS)

    1 题目源地址 http acm tju edu cn toj showp3100 html 2 源代码 TOJ 3100 Getting Gold include
  • httprunner接口自动化测试框架使用说明【保姆级教程】

    背景介绍 httprunner是国内开源的一个接口自动化框架 已经有部分公司开始使用这种框架来完成自己公司的接口自动化编写 本文主要是从简单的流程上去讲解咋使用的 PS 开发者本尊的官网教程写的是真的烂 一点也不友好 里面各种坑 本文基于h
  • Java基础——封装、继承、多态

    今天我们来了解一下面向对象的三大特性 封装 继承和多态 封装 把属性和实现细节隐藏起来 不让外界直接访问 提供公共的方法访问方式 private A 只能修饰成员 B 被private修饰的成员只能在本类中访问 外界不可以直接访问 C pr
  • cocos2d-x 地图随英雄移动

    本人刚开始学习cocos2d x游戏引擎 学到瓦片地图这块 网上有一个很经典的例子 见链接 基于Cocos2D X的砖块地图教程 一 在看到其中的地图跟随角色移动 一般情况下保持角色在屏幕中央附近 到地图边缘时移动角色 的问题时看的不大明白
  • reference to ‘ max‘ is ambiguous

    今天写C 算法的时候 声明了一个全局遍历max 来记录最短路径 编译发现遇到一个以前没遇到过的错误 reference to max is ambiguous 翻译过来就是对 max 的引用有歧义 通过查询百度发现 原因是我引用了iostr
  • c++中如何实现十进制(Dec)与十六进制(Hex)之间的相互转换

    c 中如何实现十进制 Dec 与十六进制 Hex 之间的相互转换 1 十进制 gt 十六进制 include stdafx h include iostream include string using namespace std stri
  • 富集分析(GO、KEGG、GSEA)

    library clusterProfiler library org Hs eg db GO分析与KEGG分析 GO分析需要一个基因 symbol列表 列表中为差异表达基因 一 读入数据 result lt read csv file R
  • 凡科网JS逆向后跳出的滑块验证(base64图片解码之后的破解滑块验证)

    目录 1 前提和大概思路概述 2 转换思路selenium和验证滑块图片的获取处理 3 总结 1 前提和大概思路概述 只是学习的途中有一些新的发现 分享给大家 希望对你们有帮助 凡科网的JS逆向的闭包技巧应该是典型的闭包案例 很多人都有讲解
  • STM32 USB学习笔记

    STM32 USB学习笔记 一 USB FS Device firmware library 使用固件库开发程序 需要包含几个文件 从图中可见 应用程序接口部分 有 usb pwr usb conf usb desc usb istr us
  • 中台建设&架构设计

    什么是中台 中台即企业级能力复用平台 企业级 企业级定义了中台的范围 它更多代表的是中台处理的问题在企业级别 即至少包含多条业务线或服务多个前台产品 团队 如果一个中台只为了支持一条业务线或产品线 那就不是中台 即使它用了服务化或是大数据等
  • 谷歌禁止访问测试环境

    谷歌访问测试环境接口报错 主要原因 谷歌阻止了对不安全接口的请求 解决方法 进入谷歌设置 chrome flags block insecure private network requests 将Block insecure privat
  • c++ 定时器_STM32实例定时器中断实验

    上一章我们介绍了 STM32F1的外部中断 这一章我们来学习下定时器中断 STM32F1 的定时器功能非常强大 其包含 2 个基本定时器 TIM6 TIM7 4 个通用定时器 TIM2 TIM5 和 2 个高级定时器 TIM1 TIM8 共
  • 目标检测中anchor box(先验框)的理解

    近来心血来潮 把CV领域关于目标检测的主流方法YOLOv3和Faster RCNN看了一下 对其中的先验框 anchor box 一直不太理解 在广泛地阅读了一些相关讲解后 有了一定的理解 在此记录一下 先验框的个人理解 先验框最早提出于F
  • 限定特定的IP访问服务器

    需求 windows and Linux系统仅限指定的IP或网段登陆 解决方法和思路 1 Windows设置的方法有多种 方法一 通过本机自带的防火墙设置限制IP访问 修改下面三个规则属性 点击属性 查看对应设置 设定可以访问的地址段或IP
  • 构建REST风格的Web Service

    1 什么是REST REST 是由 Roy Fielding 在他的论文 Architectural Styles and the Design of Network based Software Architectures 中提出的一个术
  • 完美卸载Visual Studio2015的方法汇总

    前言 由于各种原因 阿木寺被迫回到VS2013时代 所以此时VS2015也没有必要存在 于是再网上找了各种卸载方法 简介 方法一 适合于有点基础电脑知识的童鞋 难度 方法二 适合于小白 难度 方法三 适合于技术控 难度 方法一 1 利用当初
  • PyTorch中torchvision介绍

    TorchVision包包含流行的数据集 模型架构和用于计算机视觉的图像转换 它是PyTorch项目的一部分 TorchVison最新发布版本为v0 11 1 发布较频繁 它的license为BSD 3 Clause 它的源码位于 http

随机推荐

  • 高并发秒杀系统架构设计与实现(RuoYi-Cloud-SecKill)

    介绍 本项目是基于若依RuoYi Cloud的高并发秒杀微服务项目 RuoYi Cloud SecKill 后端采用Spring Boot Spring Cloud Alibaba MyBatis 前端采用Vue ElementUI 通过创
  • [Java]Maven项目中,子模块之间引用不同模块的方法时,会出现< 程序包:com.xxx.xxx.common.base.result 不存在>解决办法

    启动 ServiceOssApplication时报错 程序包 com atguigu guli common base result 不存在 分析思路 该程序包是另一个子模块 common下的 common utill子模块中的工具类路径
  • 【redis篇】超详细的redis安装教程,学不会你找我

    目录 第一 下载安装包 第二 上传到服务器并解压 第三 安装编译所需依赖 升级GCC 第四 开始预编译 第五 安装 第六步 启动 方式一 直接启动 方式二 守护进程启动 方式三 开机自启动 第一 下载安装包 安装包下载地址 Download
  • 百度翻译api JAVA实现

    进入官方 http api fanyi baidu com api trans product index 点击立即使用 申请得到appid和密钥 ps 这要用作开发时的常量 若当月翻译字符数 2百万 当月免费 若超过2百万字符 按照49元
  • 【C++】继承基础知识一遍过

    目录 一 概念 二 继承定义 1 继承格式 2 访问限定符与继承方式的关系 3 继承父类成员访问方式的变化 小结 三 父类与子类对象赋值转化 四 继承作用域 1 特点 2 测试题 五 派生类不一样的默认成员函数 1 构造函数 2 拷贝构造
  • 机器学习笔记九——线性模型原理以及python实现案例

    线性模型 1 线性模型概述 2 广义线性模型 3 用于回归的线性模型 3 1 线性回归 又名普通最小二乘法 3 1 1 单变量线性回归 3 1 2 多变量线性回归 3 2 岭回归 ridge regression 3 3 LASSO回归 4
  • Excel基本操作方法

    Excel基本操作方法 1 选择不连续的单元格 选择一单元格之后 按 ctrl 键不放 并单击其他需要选择的单元格 2 插入单元格 选择 开始 单元格 组 单击插入按钮 在弹出的下拉列表中选择 插入单元格选项 3 合并和拆分单元格 选择要合
  • 如何用Stata完成(shui)一篇经济学论文(七):判断语句

    目录 基本判断语句 if 逻辑判断 或且非 用 判断 基本判断语句 if 与其他语言类似 Stata中也有if if else 和while 不过我还从来没有在Stata用过后两个 秉着这个教程也是一个快速教程 这里我就只介绍if 如果大家
  • pandas 解决滑动窗口不会计算存在空值的窗口

    Pandas官方的滑动窗口文档请参考 https pandas pydata org docs reference api pandas DataFrame rolling html 解决方法 添加参数 min periods 用于指定 当
  • element ui修改table行鼠标经过样式(包括固定列)

  • 超详细SpringMVC 之 JSR303与拦截器

    一 JSR303 简介 JSR303是做服务端校验 参数验证 实现服务器校验步骤 1 做服务端参数校验 JSR303 的jar包依赖
  • 设计模式——设计模式简介和七大原则

    导航 黑马Java笔记 踩坑汇总 JavaSE JavaWeb SSM SpringBoot 瑞吉外卖 SpringCloud 黑马旅游 谷粒商城 学成在线 设计模式 牛客面试题 目录 一 通过经典面试题掌握重点 二 设计模式的目的和核心原
  • Unity3D之键盘输入

    目录 获取按键状态 检测特殊按键 获取键盘输入 自定义键位 获取按键状态 Unity的Input类提供了几个方法来获取按键的状态 GetKey GetKey方法用于检测指定按键是否被按住 if Input GetKey KeyCode Sp
  • twrp Xposed zip包脚本定制全解析

    声明 本文不对印刷机导致的任何结果承担责任 请谨慎尝试 想要研究一个新技术 最好的办法就是read the fuck source code 读源码时最直接高效的方式 当然 这很难啃 所以通常也可以配合网上一些教程来理解 但是通常 值钱的技
  • 接口学习总结

    接口测试学习总结 什么是接口测试 接口测试是项目测试的一部分 它测试的主要对象是接口 是测试系统组件间接口的一种测试 接口测试主要用于检测外部系统与所测系统之间以及内部各系统之间的交互点 测试的重点是检查数据交互 传递 和控制管理过程以及系
  • 攻防世界-level2

    攻防世界 level2 text 0804844B vulnerable function proc near CODE XREF main 11p text 0804844B text 0804844B buf byte ptr 88h
  • 备忘录莫名其妙的没了_苹果手机备忘录突然消失了该怎么办

    展开全部 恢复苹果备忘录的准备copy工具 1 iPhone手机bai及数据线du 2 开心手机恢复大师 专业的iOS数据恢复软zhi件 3 常用dao电脑 找回iPhone备忘录的详细步骤 1 将专业的苹果手机数据恢复软件 开心手机恢复大
  • 基于 Ng-zorro-antd 的企业后台模板 ng-alain

    ng alain 详细介绍 ng alain 一套基于 Ng zorro antd ANT DESIGN 的企业后台模板 README in English DEMO 快速入门 确保 node 版本 gt 6 9 0 且 npm 版本 gt
  • Oracle 自定义对象集合遍历

    功能要求 Oracle 定义对象集合 将查询结果集批量插入对象集合 循环遍历自定义对象集合属性值 定义自定义对象Object create or replace type HOUSE is object 定义biz id 属性 biz id
  • 冲击手机应用榜单Top3,高手都做了这些

    作者 舒大飞 博客地址 https juejin im post 5b1b5e29f265da6e01174b84 由于项目里之前线上版本出现过一定比例的OOM 虽然比例并不大 但是还是暴露了一定的问题 所以打算对我们App分为几个步骤进行