- 博客(123)
- 资源 (2)
- 收藏
- 关注
原创 Cmakelist语法
cmakelist语法:https://blog.csdn.net/HW140701/article/details/90203141?utm_source=app&app_version=4.5.8
2021-06-03 20:04:50 251
原创 Java对象结构
1. Java对象结构:1.1 Java对象实例:对象头:markwordklass对象实际数据:InstanceData对齐填充:-padding1.2 Java数组实例:对象头:markwordklasslength对象实际数据:ArrayData对齐填充:-padding解释:markword:用于存储对象自身的运行时数据,如哈希码(hashcode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。32位、
2021-03-19 11:02:52 243
原创 指令重排的原理
指令重排一. 指令重排的分类:编译器优化的重排指令级并行的重排内存系统的重排编译器优化重排序和指令级并行重排序不会影响程序的结果,因此程序员需要着重处理的是内存系统重排序带来的问题。二. 指令重排的原理:1.编译器优化的重排:编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序2.指令级并行的重排:为了提高CPU的执行效率,现代的CPU基本上都支持指令流水线。2.1 指令流水线:一条指令要执行要经过3个阶段:取指令、译码、执行,每个阶段都要花费一个机器周期,如果没有采
2021-03-18 21:39:53 1693
原创 Android 序列化
Parcel序列化的原理:实际存储由Parcel.cpp负责,在一块连续的内存区域的中,写入各类信息。Parcel在实例化时,拿到Parcel.cpp的实例的句柄Parcel在序列化写入数据时,遵循I-V的形式,其中I指数据类型,V指实际数据要序列化的对象实现Parcelable,其中writeToParcel()在序列化过程中获得执行时机,对象负责写入数据。CREATOR在反序列化时被调用,调用对象构造函数,将Parcel传入以让对象填充数据效率:从执行结果上看Parcelable比Seri
2021-03-17 16:05:58 133
原创 Java String的不可变性
String为什么设计成final:不可变:由于字符串的内容存储在一个char[]数组中,这个数组的引用是final类型,但是仅仅引用是final类型也不能限制数组内容的改变。因此String的不可变性是内部实现中并没有去修改这个数组的内容。为了不让这个数组的内容修改,做了一下几点:1. final修饰类:不可被继承;2. 内部实现没有对数组内容进行修改;不可变的好处:安全!1.键值的唯一性:如HashSet使用String作为key值时,如果这个String是可变的,那么HashSet键值的
2021-03-17 15:28:11 123
原创 数据结构之ArrayMap、SparseArray
ArrayMap<Key, Value>:内有两个数组:1.mHashes:记录key的hash值,索引是index;2.mArray:记录key和value值,key的索引是 2 * index,value的索引是2 * index + 1;插入和删除:1.先计算出key的hash值,找到对应的mHashes的索引index,然后比较mArray中的2 * index处的key,如果相等,则返回该索引,如果不相等,则依次遍历后续的key值,直到相等为止;2.如果是插入,则使用Sys
2021-03-15 17:01:05 157
原创 LongAdder
AtomicLong和LongAdder:为什么要引入LongAdder:AtomicLong底层是采用CAS,在高并发下,会出现大量失败并不断自旋,这比较耗性能。LongAdder就是为了解决这个问题。LongAdder原理:比如有三个ThreadA、ThreadB、ThreadC,每个线程对value增加10。对于AtomicLong,最终结果的计算始终是下面这个形式:value=10+10+10=30。多个线程执行累加时,都是串行进行的。但是对于LongAdder来说,内部有一个base变
2021-03-15 11:56:36 109 1
原创 Window、View、事件、绘制
- ActivityThread.handleResumeActivity() - Activity.makeVisible() - ViewManager.addView(DecorView) == WindowManagerImpl.addView - WindowManagerGlobal.addView() - ViewRootImpl构造:传入Display,来自Context.getDisplay() ...
2021-03-11 14:00:18 116
原创 文件头格式对应
{“扩展名”:123,“文件头标识(HEX)”:“00001A00051004”,“文件描述”:“Lotus1-2-3spreadsheet(v9)file”},{“扩展名”:“3gg;3gp;3g2”,“文件头标识(HEX)”:“000000nn66747970336770”,“文件描述”:“3rdGenerationPartnershipProject3GPP(nn=0x14)and3GPP2(nn=0x20)multimediafiles”},{“扩展名”:“7z”,“文件头标识(HEX)”:“3
2021-03-10 18:06:14 1555
原创 Android崩溃分析与处理
一. 崩溃:概念:崩溃率 UV = 发生崩溃的UV / 登录UV崩溃率小于1/1000为正常,1/10000为优秀崩溃捕获:Java层捕获:设置默认的未捕获异常处理器,Thread.setDefaultUncaughtExceptionHandler()Native层捕获:常见signal:SIGABRT 6 : 常见非法UTF8字段SIGSEGV 11: 非法内存操作信号处理函数:int sigaction(int, const struct sigaction*, str
2021-03-10 17:04:43 933
原创 LinkedHashMap摘要
LinkedHashMap:HashMap和双向链表合二为一即是LinkedHashMap。结构:继承自HashMap,因此HashMap的设计的初衷:HashMap是无序的,也就是说,迭代HashMap所得到的元素顺序并不是它们最初放置到HashMap的顺序。HashMap的这一缺点往往会造成诸多不便。LinkedHashMap增加了时间和空间上的开销,但是它通过维护一个额外的双向链表保证了迭代顺序。特别地,该迭代顺序可以是插入顺序,也可以是访问顺序。因此,根据链表中元素的顺序可以将Linked
2021-03-10 09:59:40 57
原创 C++11新特性
c++11新特性:1.auto:(1)区别:在c++11之前,auto 关键字用来指明变量的存储类型,它和 static 关键字是相对的。auto 表示变量是自动存储的,是编译器的默认规则,写不写都一样在c++11之后,使用它来做自动类型推导(2)auto 与 const 结合的用法:当类型不为引用时,auto 的推导结果将不保留表达式的 const 属性;当类型为引用时,auto 的推导结果将保留表达式的 const 属性。(3)限制:auto 不能在函数的参数中使用auto
2021-03-03 23:48:59 299
原创 宏定义
宏定义:无参宏:#define 宏名 替换文本直接文本替换有参宏:#define (参数列表) 带参数的文本将参数替换到后面的文本中如:#define MAX(x, y) (x) > (y) ? (x) : (y)#运算符:将参数替换成字符串如:#define SUM(x, y) printf(#a " + “#b” = %d\n",((a) + (b)))那么 SUM(1 + 2, 3 + 4);的输出结果为:“1 + 2 + 3 + 4 = 1
2021-02-23 23:42:21 200
原创 ConcurrentHashMap
ConcurrentHashMap的设计和原理:设计:先说一下HashMap和HashTable这两种数据结构都是数组+链表;HashMap允许多个线程同时进行存取,但是不能保证因为多线程的原因导致获取的数据不是想要的;HashTable存取都加上了Synchronized,因此只能允许同时一个线程进行存取,但是存取的数据都是想要的。为了解决HashMap和HashTable的问题,设计了ConcurrentHashMap,它同时允许多个线程同时进行存取,并且存取的数据都是想要的。Java
2021-02-23 22:35:54 393 1
原创 Mac环境下gdb调试Android ndk代码
Android从4.4开始,强制打开了SELinux,其规则是不允许一个进程attach到一个非自己的子进程或兄弟进程上进行调试的,哪怕这个进程是以root用户启动的也不行。想要知道当前SELinux的工作模式,可以在adb shell下键入getenforce命令,例如:xxx:/$ getenforceEnforcing这是在我运行Android 8.0系统的Google 模拟器上运行的结果,可以看出,其已经默认打开了强制(Enforcing)模式。所以,要想调试成功,必须要关闭SELinux的
2021-02-07 16:46:05 411
原创 JNI浅谈
分散知识点:每一个进程对应一个Runtime,每一个Runtime对应一个JavaVMExt(JavaVM),是ART虚拟机中全局唯一的虚拟机代表,可以通过Runtime::GetJavaVM函数获取。每个线程对应一个tlsPtr结构体,tlsPtr中的pthread_self代表一个线程,每个线程都有一个JNIEnvExt(JavaEnv)。根据JNI规范,目标动态库必须和一个ClassLoader对象相关联,同一个动态库不能由不同的ClassLoader对象加载JavaVM:LoadNat
2021-01-15 16:06:50 295
原创 ClassLoader小知识
JVM由4大部分组成:ClassLoader,Runtime Data Area,Execution Engine,Native Interface。栈帧包含三类信息:局部变量,执行环境,操作数栈。对比java的基本数据类型,jvm的规范中没有boolean类型。这是因为jvm中堆boolean的操作是通过int类型来进行处理的,而boolean数组则是通过byte数组来进行处理。通过查阅jvm指令集和其对应的数据类型的关系发现,大部分的指令都没有支持整数类型byte、char和short,甚至没有任
2021-01-15 16:02:49 132
原创 8086汇编语言笔记
1.地址总线(决定寻址大小)、数据总线(决定数据传输的速度)、控制总线(决定CPU对外部器件控制的能力)2.8086 物理地址寻址方式: 段地址(16位)<< 4 + 偏移地址(16)= 物理地址(20位),也就是段地址 * 16 + 偏移地址 = 可以寻址为1Mb的物理地址那么,(1).同一个物理地址可以由不同的段地址和偏移地址来构成;(2).给定一个段地址,那么通过不同的偏移地址可以构成一个范围为64k(16位)的物理地址范围;3.段寄存器:用于存储段地址的寄存器,8086有
2020-12-20 10:48:13 770 1
原创 设计模式6大原则
学习网址:https://wiki.jikexueyuan.com单一原则:定义:一个类或者一个方法只负责一项职责;问题:类T负责两个不同的职责:职责P1,职责P2。当由于职责P1需求发生改变而需要修改类T时,有可能会导致原本运行正常的职责P2功能发生故障。解决方案:遵循单一职责原则。分别建立两个类T1、T2,使T1完成职责P1功能,T2完成职责P2功能。这样,当修改类T1时,不会使职责P2发生故障风险;同理,当修改T2时,也不会使职责P1发生故障风险。里氏替换原则:子类扩展父类功能,但不能
2020-12-09 10:22:04 85
原创 Android UI性能优化
对于Android的UI性能优化,我一般从5个途径来分析:1.Debug GPU overdraw;2.Android CPU Profile;3.dumpsys gfxinfo;4.Profile GPU Rendering;5.Systrace。我们从这5个途径一一来说明。一.Debug GPU overdraw这个是用于检测布局优化的工具,这个想必大家都非常熟悉了,在手机的开发者选项中打开”Debug GPU overdraw“,就能看到咱们的布局中有各种色块,色块的说明,一般避免出现
2020-12-08 17:14:42 2963
原创 Android 11 跳转权限
<queries> <intent> <action android:name="android.intent.action.SENDTO" /> <data android:scheme="mailto" /> </intent> <intent> <action android:name="android.intent.action.VIEW" /> <data and.
2020-11-20 09:45:28 648
原创 编译器全貌介绍
·第一段叫前端(Frontend):其输入为源代码,输出为中间表示(IntermediateRepresentation,简写为IR,IR也被称作中间代码、中间语言)。IR没有标准语法。各编译器都可以自定义IR。比如LLVM就有LLVM IR,而Java字节码也是一种IR。前端的工作主要是解析输入的源码,并对其进行词法分析、语法分析、语义分析、生成对应的IR等。·第二段叫优化器(Optimizer):优化器的输入是未优化的IR,输出是优化后的IR。常用的优化手段有循环优化、常量传播和折叠、无用代码消..
2020-10-06 15:07:08 281
转载 linux下gdb调试方法与技巧整理
目录一、gdb简介 二、gdb使用流程 1、启动gdb 2、查看源码 3、运行程序 4、设置断点 5、单步执行 6、查看变量 7、退出gdb 三、gdb基本使用命令 1、运行命令 2、设置断点 3、查看源码 4、打印表达式 5、查看运行信息 6、分割窗口 7、cgdb强大工具 四、总结一、gdb简介GDB是一个由GNU开源组织发布的、UNIX/LINUX操作系统下的、基于命令行的、功能强大的程序调试工具。 对于一名Li.
2020-10-06 14:22:50 1488
原创 库与运行库 内存
库与运行库 内存一.栈栈保存了一个函数调用所需要的维护信息,称为堆栈帧或活动记录,包含的内容:函数的返回地址和参数临时变量:包含函数的非静态局部变量以及编译器自动生成的其他临时变量保存的上下文:包括在函数调用前后需要保持不变的寄存器一个函数的活动记录用ebp和esp两个寄存器划定范围。esp寄存器始终指向栈的顶部,同时也就指向了当前函数的活动记录的顶部。而ebp寄存器指向了函数活动记录的一个固定位置,ebp寄存器又被称为栈指针,ebp指向的数据是调用该函数前ebp的值,这样在函数返回的时候,
2020-09-22 23:40:34 167
转载 内存映射原理
首先说说这篇文章要解决什么问题?1.虚拟内存与内存映射文件的区别与联系.2.内存映射文件的原理.3.内存映射文件的效率.4.传统IO和内存映射效率对比.虚拟内存与内存映射文件的区别与联系 二者的联系虚拟内存和内存映射文件都是将一部分内容加载到,另一部分放在磁盘上的一种机制,二者都是应用程序动态性的基础,由于二者的虚拟性,对于用户都是透明的.虚拟内存其实就是硬盘的一部分,是计算机RAM与硬盘的数据交换区,因为实际的物理内存可能远小于进程的地址空间,这就需要把内存中暂时不用到...
2020-09-11 08:26:27 718
原创 动态链接
动态链接命令:gcc:-static:产生静态库-shared:产生共享库一.静态链接和动态链接的优缺点:静态链接:空间的浪费:静态链接,程序最后都会链接成一个可执行文件,那么功能相同的模块(可以用来共享),在每一个需要使用的程序中都有一个份,这样就会对计算机的内存和磁盘空间造成浪费。更新、部署、发布困难:当需要更新功能相同的模块(可以用来共享)时,所有的程序需要重新连接。动态链接:不对那些组成程序的目标文件进行链接,等到程序要运行时才进行链接。节省空间,提供缓存命中率:在内
2020-09-01 16:15:29 913
原创 C++中nullptr和NULL
C++中nullptr和NULL:在C99里面,NULL可以被定义为0或者0L(32位和64位的区别),或者直接就是由0或者0L转成的void*。问题:函数重载的问题:void func(int a);void func(void *a);对于上面两个重载的函数,func(NULL)会使用上面那个版本,但是> func(nullptr)会使用下面这个版本。模板匹配问题:struct Data{Data(char *a){}};对于上面这个结构体,std::make_
2020-08-27 17:55:23 661
原创 可执行文件的装载与进程
可执行文件的装载与进程命令:readelf:-l:查看ELF可执行文件的程序头表(保存Segment信息)一. 装载的方式:程序运行时是有局部性原理的,所以我们将程序最常见的部分驻留在内存中,而将一些不太常见的数据存放在磁盘里面,这就是动态装入的基本原理。常用的动态装载的方式:页映射页映射:不是一次性将程序的所有数据和指令都装入内存,而是将内存和所有磁盘中的数据和指令按照“页”为单位划分成若干个页,以后所有的装载和操作的单位就是页。二. 从操作系统角度看可执行文件的装载:一个进程最关键
2020-08-26 09:03:46 226
原创 静态链接
静态链接命令:objdump:-r:查看目标文件的重定位表ld:-e:-e main将main函数作为程序入口,ld链接器默认的程序入口为_start一.空间与地址分配:多个目标文件链接过程是将相似段合并,一般采用两步链接的方法:第一步:空间与地址分配:扫描所有的输入目标文件,并且获得它们的各个段的长度、属性和位置,并且将输入目标文件中的符号表中所有的符号定义和符号引用收集起来,统一放到一个全局符号表。这一步中,链接器将能够获取所有输入目标文件的段长度,并且将它们合并,计算出输出文
2020-08-24 23:15:21 233
原创 ELF文件里有什么
ELF文件里有什么一.文件头:ELF文件的开头是一个“文件头”,它描述了整个文件的魔数:用来描述文件的类型、字节序、ELF的主版本号,其余的暂时没有使用。文件属性,包括文件是否可执行、是静态链接还是动态链接及入口地址(如果是可执行文件)、目标硬件、目标操作系统等信息,还包括段表,段表是一个描述文件中各个段的数组,描述各个段在文件中的偏移位置及段的属性等。二.分段的意义:数据区域对于进程来说是可读写的,而指令区域对于进程来说是只读的,所以这两个虚拟区域的权限可以被分别设置成可读写和
2020-08-22 15:43:44 388
转载 java 获取当前方法的调用栈
本文的出发点在于处理现场问题时,想看到方法的调用过程StackTrace(堆栈轨迹)存放的本文的出发点在于处理现场问题时,想看到方法的调用过程StackTrace(堆栈轨迹)存放的就是方法调用栈的信息,每次调用一个方法会产生一个方法栈,当前方法调用另外一个方法时会使用栈将当前方法的现场信息保存在此方法栈当中,获取这个栈就可以得到方法调用的详细过程。StackTraceElement stack[] = Thread.currentThread().getStackTrace(); ...
2020-08-18 20:40:04 3162
原创 性能优化-内存分析工具Mat
Mat使用MAT工具可以帮助开发者定位导致内存泄漏的对象,以及发现大的内存对象,然后解决内存泄漏并通过优化内存对象,以达到减少内存消耗的目的。使用步骤在https://eclipse.org/mat/downloads.php下载MAT客户端。打开Mat:点击右键打开刚刚下载好的Mat的包路径,在MacOS目录下,使用命令./MemoryAnalyzer -data ./workspace创建工作空间,就能打开Mat图形化界面了。sh脚本如下:cd /Android_Tools/mat/mat
2020-08-06 11:21:42 855
转载 Java内存泄漏分析系列之七:使用MAT的Histogram和Dominator Tree定位溢出源
基础概念先列出几个基础的概念:Shallow Heap 和 Retained HeapShallow Heap表示对象本身占用内存的大小,不包含对其他对象的引用,也就是对象头加成员变量(不是成员变量的值)的总和。Retained Heap是该对象自己的Shallow Heap,并加上从该对象能直接或间接访问到对象的Shallow Heap之和。换句话说,Retained Heap是该对象GC之后所能回收到内存的总和。把内存中的对象看成下图中的节点,并且对象和对象之间互相引用。这里有一个特
2020-08-06 11:19:35 503
转载 MAT使用进阶
Java的内存泄露Java中的内存泄露主要特征:可达,无用 无用指的是创建了但是不再使用之后没有释放 能重用但是却创建了新的对象进行处理MAT使用技巧使用Android Studio Dump内存文件Android Studio的最新版本可以直接获取hprof文件:Android-Studio然后选择文件,点击右键转换成标准的hprof文件,就可以在MAT中打开了。在使用使用Eclipse或者AndroidStudio抓内存之前,一定要手动点击 Initiate GC按钮
2020-08-06 11:17:35 490
原创 openssl Android平台编译脚本
#!/bin/sh# Android ndk的路径ANDROID_NDK=/Android_Tools/android-ndk-r20b# 需要的openssl版本OPENSSL_VERSION=1.1.1fAPI_LEVEL=23# 编译的临时路径以及输出路径BUILD_DIR=/tmp/openssl_android_buildOUT_DIR=/tmp/openssl_android# 需要编译的多个cpu架构集合BUILD_TARGETS="armeabi armeab.
2020-07-22 14:26:04 352
原创 线程池简单介绍
线程池:(1)FixedThreadPool:可重用固定线程数的线程池- 固定线程池,那么corePoolSize和maximumPoolSize是相同大小;- keepAliveTime为0,表示空闲线程会立刻终止;- 采用无界阻塞队列LinkedBlockingQueue,大小为Integer.MAX_VALUE,因此只有在线程池shutdown()或shutdownNow()后才会拒绝任务。(2)SingleThreadExecutor:单个Worker线程的Executor- 线程数
2020-07-02 17:57:54 150
原创 Java并发包——并发工具
Java并发工具:知识点:Thread.join()是通过Object.wait()来实现的,Thread.join(millis)是通过Object,wait(millis)来实现的。当线程执行完后,由JVM调用Thread.unpark$()方法->Object.notifyAll()。(1)CountDownLatch(计数器):相当于一个计数器,它的构造函数会传入一个int值作为初始计数值。但是这个计数器是一次性的,不可重复使用。- await():线程调用该方法,相当于这个线程需
2020-07-01 15:20:52 233
openssl_android.sh
2020-07-22
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人