android oom 全解析

  Android oom 有时出现很频繁,这一般不是Android设计的问题,一般是我们的问题。

  就我的经验而言,出现oom,无非主要是以下几个方面:

  一、加载对象过大

  二、相应资源过多,没有来不及释放。

  解决这样的问题,也有一下几个方面:

  一:在内存引用上做些处理,常用的有软引用、强化引用、弱引用

  二:在内存中加载图片时直接在内存中做处理,如:边界压缩.
  三:动态回收内存
  四:优化Dalvik虚拟机的堆内存分配
  五:自定义堆内存大小

  可真有这么简单吗,不见得,看我娓娓道来:

  软引用(SoftReference)、虚引用(PhantomRefrence)、弱引用(WeakReference),这三个类是对heap中java对象的应用,通过这个三个类可以和gc做简单的交互,除了这三个以外还有一个是最常用的强引用.

  强引用,例如下面代码:

  Object o=new Object();       
  Object o1=o;

  上面代码中第一句是在heap堆中创建新的Object对象通过o引用这个对象,第二句是通过o建立o1到new Object()这个heap堆中的对象的引用,这两个引用都是强引用.只要存在对heap中对象的引用,gc就不会收集该对象.如果通过如下代码:

  o=null;         

  o1=null;

  heap中对象有强可及对象、软可及对象、弱可及对象、虚可及对象和不可到达对象。应用的强弱顺序是强、软、弱、和虚。对于对象是属于哪种可及的对象,由他的最强的引用决定。如下:

String abc=new String("abc");  //1
SoftReference<String> abcSoftRef=new SoftReference<String>(abc);  //2
WeakReference<String> abcWeakRef = new WeakReference<String>(abc); //3
abc=null; //4
abcSoftRef.clear();//5在此例中,透过 get() 可以取得此 Reference 的所指到的对象,如果返回值为 null 的话,代表此对象已经被清除。这类的技巧,在设计 Optimizer 或 Debugger 这类的程序时常会用到,因为这类程序需要取得某对象的信息,但是不可以 影响此对象的垃圾收集。

  虚引用
   就是没有的意思,建立虚引用之后通过get方法返回结果始终为null,通过源代码你会发现,虚引用通向会把引用的对象写进referent,只是get方法返回结果为null.先看一下和gc交互的过程在说一下他的作用. 
     不把referent设置为null, 直接把heap中的new String("abc")对象设置为可结束的(finalizable).
      与软引用和弱引用不同, 先把PhantomRefrence对象添加到它的ReferenceQueue中.然后在释放虚可及的对象. 你会发现在收集heap中的new String("abc")对象之前,你就可以做一些其他的事情.通过以下代码可以了解他的作用.

  虽然这些常见引用,能够使其gc回收,但是gc又不是非常的智能了,因而oom乱免。

  二:在内存中加载图片时直接在内存中做处理。

  尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图,因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存。

  因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的 source,decodeStream最大的秘密在于其直接调用JNI>>nativeDecodeAsset()来完成decode,无需再使用java层的createBitmap,从而节省了java层的空间。

  如果在读取时加上图片的Config参数,可以跟有效减少加载的内存,从而跟有效阻止抛out of Memory异常,另外,decodeStream直接拿的图片来读取字节码了, 不会根据机器的各种分辨率来自动适应, 使用了decodeStream之后,需要在hdpi和mdpi,ldpi中配置相应的图片资源, 否则在不同分辨率机器上都是同样大小(像素点数量),显示出来的大小就不对了。

  另外,以下方式也大有帮助:

InputStream is = this.getResources().openRawResource(R.drawable.pic1); BitmapFactory.Options options=new BitmapFactory.Options(); options.inJustDecodeBounds = false; options.inSampleSize = 10;   //width,hight设为原来的十分一Bitmap btp =BitmapFactory.decodeStream(is,null,options); if(!bmp.isRecycle() ){ bmp.recycle()   //回收图片所占的内存system.gc()  //提醒系统及时回收
} 

  以下奉上一个方法,以最省内存的方式读取本地资源的图片

/***  *@paramcontext *@paramresId *@return */ public static Bitmap readBitMap(Context context, int resId){ BitmapFactory.Options opt = new BitmapFactory.Options(); opt.inPreferredConfig = Bitmap.Config.RGB_565; opt.inPurgeable = true; opt.inInputShareable = true; //获取资源图片InputStream is = context.getResources().openRawResource(resId); return BitmapFactory.decodeStream(is,null,opt); }

昨天在模拟器上给gallery放入图片的时候,出现java.lang.OutOfMemoryError: bitmap size exceeds VM budget 异常,图像大小超过了RAM内存。
 
      模拟器RAM比较小,只有8M内存,当我放入的大量的图片(每个100多K左右),就出现上面的原因。 
由于每张图片先前是压缩的情况,放入到Bitmap的时候,大小会变大,导致超出RAM内存,具体解决办法如下:

```java
//解决加载图片 内存溢出的问题//Options 只保存图片尺寸大小,不保存图片到内存BitmapFactory.Options opts = new BitmapFactory.Options(); //缩放的比例,缩放是很难按准备的比例进行缩放的,其值表明缩放的倍数,SDK中建议其值是2的指数值,值越大会导致图片不清晰opts.inSampleSize = 4; Bitmap bmp = null; bmp = BitmapFactory.decodeResource(getResources(), mImageIds[position],opts);                              ...               //回收bmp.recycle(); 

通过上面的方式解决了,但是这并不是最完美的解决方式。

通过一些了解,得知如下:

优化Dalvik虚拟机的堆内存分配

对于Android平台来说,其托管层使用的Dalvik JavaVM从目前的表现来看还有很多地方可以优化处理,比如我们在开发一些大型游戏或耗资源的应用中可能考虑手动干涉GC处理,使用dalvik.system.VMRuntime类提供的setTargetHeapUtilization方法可以增强程序堆内存的处理效率。当然具体原理我们可以参考开源工程,这里我们仅说下使用方法: private final static floatTARGET_HEAP_UTILIZATION = 0.75f; 在程序onCreate时就可以调用VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION);即可。

Android堆内存也可自己定义大小

对于一些Android项目,影响性能瓶颈的主要是Android自己内存管理机制问题,目前手机厂商对RAM都比较吝啬,对于软件的流畅性来说RAM对性能的影响十分敏感,除了 优化Dalvik虚拟机的堆内存分配外,我们还可以强制定义自己软件的对内存大小,我们使用Dalvik提供的dalvik.system.VMRuntime类来设置最小堆内存为例:

private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ;

VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE); //设置最小heap内存为6MB大小。当然对于内存吃紧来说还可以通过手动干涉GC去处理

bitmap 设置图片尺寸,避免 内存溢出 OutOfMemoryError的优化方法

★android 中用bitmap 时很容易内存溢出,报如下错误:Java.lang.OutOfMemoryError : bitmap size exceeds VM budget

● 主要是加上这段:

BitmapFactory.Options options = new BitmapFactory.Options(); 
                options.inSampleSize = 2; 
  
● eg1:(通过Uri取图片)

private ImageView preview;
BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 2;//图片宽高都为原来的二分之一,即图片为原来的四分之一Bitmap bitmap = BitmapFactory.decodeStream(cr .openInputStream(uri), null, options); preview.setImageBitmap(bitmap); 

以上代码可以优化内存溢出,但它只是改变图片大小,并不能彻底解决内存溢出。
● eg2:(通过路径去图片)

private ImageView preview;
private String fileName= "/sdcard/DCIM/Camera/2010-05-14 16.01.44.jpg";
BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 2;//图片宽高都为原来的二分之一,即图片为原来的四分之一Bitmap b = BitmapFactory.decodeFile(fileName, options); preview.setImageBitmap(b); filePath.setText(fileName); 

    这样,能够压缩足够的比例,但是对于小内存手机,特别是那种16mheap的手机是避免不了了。

  三.动态分配内存

  动态内存管理DMM(Dynamic Memory Management)是从Heap中直接分配内存和回收内存。

  有两种方法实现动态内存管理。

  一是显示内存管理EMM(Explicit Memory Management)。
在EMM方式,内存从Heap中进行分配,用完后手动回收。程序使用malloc()函数分配整数数组,并使用free()函数释放分配的内存。

  二是自动内存管理AMM(Automatic Memory Management)。
AMM也可叫垃圾回收器(Garbage Collection)。Java编程语言实现了AMM,与EMM不同,Run-time system关注已分配的内存空间,一旦不再使用,立即回收。

  无论是EMM还是AMM,所有的Heap管理计划都面临一些共同的问题和前在的缺陷:
  1)内部碎片(Internal Fragmentation)
当内存有浪费时,内部碎片出现。因为内存请求可导致分配的内存块过大。比如请求128字节的存储空间,结果Run-time system分配了512字节。

  2)外部碎片(External Fragmentation)
当一系列的内存请求留下了数个有效的内存块,但这些内存块的大小均不能满足新请求服务,此时出现外部碎片。

  3)基于定位的延迟(Location-based Latency)
延迟问题出现在两个数据值存储得相隔很远,导致访问时间增加。

  EMM往往比AMM更快。
  EMM与AMM比较表:
——————————————————————————————————————
                                 EMM                                        AMM
——————————————————————————————————————
Benefits     尺寸更小、速度更快、易控制         stay focused on domain issues
Costs        复杂、记账、内存泄露、指针悬空           不错的性能
——————————————————————————————————————

早期的垃圾回收器非常慢,往往占用50%的执行时间。

垃圾回收器理论产生于1959年,Dan Edwards在Lisp编程语言的开发时实现了第一个垃圾回收器。

垃圾回收器有三种基本的经典算法:

1)Reference counting(引用计数)
基本思想是:当对象创建并赋值时该对象的引用计数器置1,每当对象给任意变量赋值时,引用记数+1;一旦退出作用域则引用记数-1。一旦引用记数变为0,则该对象可以被垃圾回收。
引用记数有其相应的优势:对程序的执行来说,每次操作只需要花费很小块的时间。这对于不能被过长中断的实时系统来说有着天然的优势。
但也有其不足:不能够检测到环(两个对象的互相引用);同时在每次增加或者减少引用记数的时候比较费时间。
在现代的垃圾回收算法中,引用记数已经不再使用。

2)Mark-sweep(标记清理)
基本思想是:每次从根集出发寻找所有的引用(称为活对象),每找到一个,则对其做出标记,当追踪完成之后,所有的未标记对象便是需要回收的垃圾。
也叫追踪算法,基于标记并清除。这个垃圾回收步骤分为两个阶段:在标记阶段,垃圾回收器遍历整棵引用树并标记每一个遇到的对象。在清除阶段,未标记的对象被释放,并使其在内存中可用。

3)Copying collection(复制收集)
基本思想是:将内存划分为两块,一块是当前正在使用;另一块是当前未用。每次分配时使用当前正在使用内存,当无可用内存时,对该区域内存进行标记,并将标记的对象全部拷贝到当前未用内存区,这是反转两区域,即当前可用区域变为当前未用,而当前未用变为当前可用,继续执行该算法。
拷贝算法需要停止所有的程序活动,然后开始冗长而繁忙的copy工作。这点是其不利的地方。

近年来还有两种算法:

1)Generational garbage collection(分代)
其思想依据是:
  (1) 被大多数程序创建的大多数对象有着非常短的生存期。
  (2) 被大多数程序创建的部分对象有着非常长的生存期。
简单拷贝算法的主要不足是它们花费了更多的时间去拷贝了一些长期生存的对象。
而分代算法的基本思想是:将内存区域分两块(或更多),其中一块代表年轻代,另一块代表老的一代。针对不同的特点,对年轻一代的垃圾收集更为频繁,对老代的收集则较少,每次经过年轻一代的垃圾回收总会有未被收集的活对象,这些活对象经过收集之后会增加成熟度,当成熟度到达一定程度,则将其放进老代内存块中。
分代算法很好的实现了垃圾回收的动态性,同时避免了内存碎片,是目前许多JVM使用的垃圾回收算法。

2)Conservative garbage collection(保守)

哪一种算法最好?答案是没有最好。

EMM作为很常用的垃圾回收算法,有5种基本方法:
  1)Table-driven algorithms
  表驱动算法把内存分为固定尺寸的块集合。这些块使用抽象数据结构进行索引。比如一个bit对应一个块,用0和1表示是否分配。不利因素:位映射依赖于内存块的尺寸;另外,搜索一系列的空闲内存块可能需要搜索整个bit映射表,这影响性能。

  2)Sequential fit
顺序适应算法允许内存分为不同的尺寸。此算法跟踪已分配和空闲的Heap,标记空闲块的起始地址和结束地址。它有三种子分类:
  (1) First fit(首次适应)——分配找到的第一个适合内存请求的块
  (2) Best fit(最佳适应)——分配最适合内存请求的块
  (3) Worst fit(最不适应)——分配最大的块给内存请求

3)Buddy systems
  Buddy systems算法的主要目的是加速已分配内存在释放后的合并速度。显示内存管理EMM使用Buddy systems算法可能导致内部碎片。

4)Segregated storage
  隔离存储技术涉及到把Heap分成多个区域(zone),并为每个区域采用不同的内存管理计划。这是很有效的方法。

5)Sub-allocators
  子配置技术尝试解决在Run-time System下分配大块内存并单独管理的内存分配问题。换句话说,程序完全负责自己的私有存储堆(stockpile)的内存分配和回收,无需run-time System的帮助。它可能带来额外的复杂性,但是你可以显著地提高性能。在1990年的《C Compiler Design》一书中,Allen Holub就极好地利用了Sub-allocators来加速其编译器的实现。

  注意,显示内存管理EMM必须是灵活的,能够响应数种不同类型的请求。

  最后,使用EMM还是使用AMM?这是一个Religious question,凭个人喜好。EMM在复杂的开销下实现了速度和控制。AMM牺牲了性能,但换来了简单性。

  无论是emm,amm分配内存,出现了oom的问题,由于加载内存过大也是在所难免。

  四。优化Dalvik虚拟机的堆内存分配

  对于Android平台来说,其托管层使用的Dalvik Java VM从目前的表现来看还有很多地方可以优化处理,比如我们在开发一些大型游戏或耗资源的应用中可能考虑手动干涉GC处理,使用dalvik.system.VMRuntime类提供的setTargetHeapUtilization方法可以增强程序堆内存的处理效率。当然具体原理我们可以参考开源工程,这里我们仅说下使用方法:private final static float TARGET_HEAP_UTILIZATION = 0.75f;在程序onCreate时就可以调用VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION);即可。

Android堆内存也可自己定义大小

对于一些Android项目,影响性能瓶颈的主要是Android自己内存管理机制问题,目前手机厂商对RAM都比较吝啬,对于软件的流畅性来说RAM对性能的影响十分敏感,除了 优化Dalvik虚拟机的堆内存分配外,我们还可以强制定义自己软件的堆内存大小,我们使用Dalvik提供的 dalvik.system.VMRuntime类来设置最小堆内存为例:

private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ;

VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE); //设置最小heap内存为6MB大小。当然对于内存吃紧来说还可以通过手动干涉GC去处理

  注意了,这个设置dalvik虚拟机的配置的方法对Android4.0 设置无效。

  这就是我对Android的oom的一点看法.

标签: android
绿色通道: 好文要顶 关注我 收藏该文 与我联系

laozhu1124
关注 - 16
粉丝 - 351

+加关注

1
0
(请您对文章做出评价)

« 上一篇: Android推送分析
» 下一篇: 论程序员的简历

posted on 2014-04-13 21:05 laozhu1124 阅读(3145) 评论(0) 编辑 收藏

刷新评论 刷新页面 返回顶部
style="border-width: 0px; vertical-align: bottom; " id="google_ads_iframe_/1090369/cnblogs_blogpost_C1_sitehome_0" height="250" marginheight="0" src="http://www.cnblogs.com/manuosex/p/3661762.html" frameborder="0" width="300" allowtransparency="" name="google_ads_iframe_/1090369/cnblogs_blogpost_C1_sitehome_0" marginwidth="0" scrolling="no">
最新IT新闻:
· 11年了!美国宇航局庆祝机遇号生日
· 博士中关村买电脑被骗 七个博士没搞定一个商户
· 9个关于自拍的恶趣味真相
· “中国微波之父”逝世 90多岁仍在写论文
· 微软前高管建议:没做到前不要妄自承诺
» 更多新闻...
最新知识库文章:

· 浅析数据化设计思维
· 门户级UGC系统的技术进化路线
· 亿级用户下的新浪微博平台架构
· 技术团队的情绪与效率
· 关于请求被挂起页面加载缓慢问题的追查

» 更多知识库文章...

< 2015年1月 >
28 29 30 31 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
1 2 3 4 5 6 7

导航

  • 博客园
  • 首页
  • 新随笔
  • 联系
  • 订阅
  • 管理

统计

  • 随笔 - 217
  • 文章 - 0
  • 评论 - 535
  • 引用 - 0

公告

昵称: laozhu1124
园龄: 2年5个月
粉丝: 351
关注: 16

+加关注

搜索

 

常用链接

  • 我的随笔
  • 我的评论
  • 我的参与
  • 最新评论
  • 我的标签

最新随笔

  • 1. android动手写控件系列——老猪叫你写相机
  • 2. android bundle 对象 序列化
  • 3. 如何提高你代码质量
  • 4. java Field 二三事
  • 5. 什么是“攻城狮”
  • 6. 战斗bug技巧全攻略
  • 7. 谁为你的app捡肥皂
  • 8. 何为程序员思维
  • 9. unity 3d yield 用法总结
  • 10. a,b盘去哪儿?

我的标签

  • android(84)
  • metroUI(48)
  • win8(47)
  • 开发(43)
  • 数据结构(33)
  • C#(33)
  • 算法(28)
  • 程序(10)
  • 底层(7)
  • mongodb(7)
  • 更多

随笔档案(217)

  • 2014年11月 (1)
  • 2014年8月 (3)
  • 2014年7月 (1)
  • 2014年6月 (1)
  • 2014年5月 (13)
  • 2014年4月 (20)
  • 2014年3月 (36)
  • 2014年2月 (4)
  • 2013年11月 (10)
  • 2013年8月 (3)
  • 2013年7月 (12)
  • 2012年12月 (31)
  • 2012年11月 (29)
  • 2012年10月 (25)
  • 2012年9月 (27)
  • 2012年8月 (1)

积分与排名

  • 积分 - 187401
  • 排名 - 657

阅读排行榜

  • 1. android 无法生成R文件的原因剖析(11544)
  • 2. 手把手玩转win8开发系列课程(1)(5788)
  • 3. Android下 使用百度地图sdk(4668)
  • 4. .net你不行——是你的父亲把你封装的太死,还是你的子孙们太懒,未把你发扬光大。(3488)
  • 5. Caused by: java.lang.UnsatisfiedLinkError...解决经历(3214)

评论排行榜

  • 1. .net你不行——是你的父亲把你封装的太死,还是你的子孙们太懒,未把你发扬光大。(42)
  • 2. 一道百度之星编程大赛题的随笔联想·(2)(29)
  • 3. 玩转2048,不如搞定2048(29)
  • 4. 同样加班 不同收获(23)
  • 5. C#数据结构与算法揭秘一(16)

推荐排行榜

  • 1. 玩转2048,不如搞定2048(13)
  • 2. 何为程序员思维(10)
  • 3. 同样加班 不同收获(10)
  • 4. win8 开发之旅(15) --足球游戏揭秘(1)(7)
  • 5. C#数据结构与算法揭秘五(7)

style="DISPLAY: none; VISIBILITY: hidden" src="http://tpc.googlesyndication.com/safeframe/1-0-1/html/container.html"> 淘宝免费计数器

关于 android oom(内存溢出的分析)相关推荐

  1. android 内存溢出问题分析

    最近的项目中,内存一直再增长,但是不知道是什么问题,导致内存溢出,在网上看到了这么一篇关于内存分析与管理的文章,解决了部分问题,感觉这篇文章还不错,就转帖到我的blog上了,希望对大家有所帮助.如果哪 ...

  2. 彻底解决Android 拍照 内存溢出 Out of Memory的问题

    内存溢出相信做过编程的人都知道一二,这里说Android 内存溢出的问题:.问题描述:Android下的相机在独自使用时,拍照没有问题,通过我们的代码调用时,也正常,但是更换了不同厂商的平板,ROM由 ...

  3. 关于Android 的内存泄露及分析

    博客园 首页 新随笔 联系 管理 订阅 随笔- 137  文章- 6  评论- 145  关于Android 的内存泄露及分析 一. Android的内存机制 Android的程序由Java语言编写, ...

  4. 生产内存溢出定位分析

    生产内存溢出定位分析 具体生产环境大多为linux系统,此处以linux系统为示例. 1.什么是oom? 英文全称"Out Of Memory",译为 "内存不足&quo ...

  5. 转:记一次linux oom内存溢出排查过程

    @转:记一次linux oom内存溢出排查过程 记一次linux oom内存溢出排查过程 2018年08月16日 14:13:49 enchanterblue 阅读数 4099更多 分类专栏: --- ...

  6. 面试两连击:线上JVM GC问题和OOM内存溢出的解决方案,聊聊呗!

    点击上方石杉的架构笔记,右上角选择"设为星标" 每日早8点半,技术文章准时送上 公众号后台回复"学习",获取作者独家秘制精品资料 往期文章 BAT 面试官是如何 ...

  7. Xamarin Android提示内存溢出错误

    Xamarin Android提示内存溢出错误 错误信息:java.lang.OutOfMemoryError, Consider increasing the value of $(JavaMaxi ...

  8. android 避内存溢出,Android避免内存溢出(Out of Memory)方法总结

    Android避免内存溢出(Out of Memory)方法总 结 避免内存溢出的方法,主要是对以下三个方面对程序进行优化武汉Android培训 内存引用 在处理内存引用之前,我们先来复习下什么是强引 ...

  9. android手机内存使用情况分析

    android手机内存使用情况分析         通常客户经常纠结手机内存的使用率不合理,占有的内存太大,可用内存很少,客户往往需要给出解决方案或在给出原因,那么你首先需要知道手机的内存都被什么应用 ...

  10. JAVA内存分析:基于dump内存溢出快照分析

    JAVA内存分析 JAVA内存分析一:基于dump内存溢出快照分析 JAVA内存分析二:idea集成jprofiler查看JVM内存使用情况 JAVA内存分析三:使用JDK自带工具进行内存和CPU分析 ...

最新文章

  1. Traveller项目介绍
  2. windows自动关闭无响应程序
  3. 获取打印的html代码怎么写,javascript如何输出?
  4. oracle逻辑备份和物理备份,oracle数据库物理备份和逻辑备份区别
  5. boost::prior用法的测试程序
  6. Spring boot升级到2.3.2.Release和Spring framework升级到5.28.Release踩过的坑
  7. 带你手写基于 Spring 的可插拔式 RPC 框架(四)代理类的注入与服务启动
  8. 计算机应用基础教程上机指导及题库,计算机应用基础习题及上机指导
  9. 我喜欢的 Linux shell 玩法
  10. jquery图表统计插件-highcharts详解
  11. oracle删除schema下所有对象,清空Schema中所有对象的步骤
  12. IOS上架时及开发注意事项
  13. 阿里天池比赛——地表建筑物识别
  14. 项目4-分数类和整型数的四则运算
  15. c语言软件中ovr怎么取消,OVR Toolkit
  16. iia期是第几期_IIa期和IIb期的定义,区别
  17. oracle计算timestamp差,Oracle 计算timestamp和date类型的时间差
  18. mac安装win7之后鼠标失灵_解决最新MAC(usb3.0)安装windows7鼠标不动造成无法安装都问题...
  19. 计算机应用能力考试xp模拟题,2014年计算机应用能力考试XP考试模拟试题一
  20. 网页中使用Unicode字符,常用Unicode字符收集(转载多篇)

热门文章

  1. Python中的else用法
  2. 虽迟但到,我的2022年终总结
  3. 项目中使用svg格式的字符串转换图片并把图片插入到word和pdf文档
  4. c语言欧拉函数,欧拉函数
  5. 网络运维(Python自动化运维)考点
  6. 目标检测算法回顾之Anchor free篇章
  7. JavaScript Emoji 表情库_js 类似于qq微信的表情库
  8. solidity学习笔记第1天
  9. Buildroot 系统设置开机密码登录-迅为RK3588开发板
  10. 基石为勤能补拙的迷宫之旅——第三天(Python基本数据类型,与用户交互(输出输入),运算符)