乱码三千 – 分享实用IT技术

乱码三千 – 码出一个新世界


  • 首页

  • 归档

  • 搜索

java五大排序算法之选择排序

发表于 2019-12-09

一.选择排序介绍

选出最小的一个数与第一个位置的数交换

二.选择排序原理分析

第1趟比较:拿第1个元素依次和它后面的每个元素进行比较,如果第1个元素大于后面某个元素,交换它们,经过第1趟比较,数组中最小的元素被选出,它被排在第一位

第2趟比较:拿第2个元素依次和它后面的每个元素进行比较,如果第2个元素大于后面某个元素,交换它们,经过第2趟比较,数组中第2小的元素被选出,它被排在第二位

……

第n-1趟比较:第n-1个元素和第n个元素作比较,如果第n-1个元素大于第n个元素,交换它们

三.选择排序代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static void selectionSort(int[] nums) {

if (nums == null || nums.length < 2) {
return;
}

for(int i = 0; i < nums.length - 1; i++) {
for(int j = i + 1; j < nums.length; j++) {
if(nums[i] > nums[j]) {
swap(nums, i, j);
}
}
}

}

public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}

四.选择排序的优化

使用临时变量存储最小值的角标值,减少交换的次数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static void selectSort(int[] numbers) {
int size = numbers.length; // 数组长度
int temp = 0; // 中间变量
for (int i = 0; i < size-1; i++) {
int k = i; // 待确定的位置
// 选择出应该在第i个位置的数
for (int j = size - 1; j > i; j--) {
if (numbers[j] < numbers[k]) {
k = j;
}
}
// 交换两个数
temp = numbers[i];
numbers[i] = numbers[k];
numbers[k] = temp;
}
}

五.选择排序的时间复杂度

时间复杂度:O(n²)

空间复杂度:O(1),只需要一个附加程序单元用于交换

稳定性:选择排序是不稳定的排序算法,因为无法保证值相等的元素的相对位置不变,例如 [3, 4, 3, 1, 5]这个数组,第一次交换,第一个3和1交换位置,此时原来两个3的相对位置发生了变化。

本帖附件

点击下载

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

Java面试题之TCP和UDP的区别

发表于 2019-12-09

网络层的划分

一 网络层的划分

  • 物理层 :负责在物理线路上传输原始的二进制数据(0和1),该层数据以比特流的形式传输

  • 链路层: 负责在通信的实体间建立数据链路连接,该层数据以帧的形式传输

  • 网络层: 负责创建逻辑链路,以及实现数据包的分片和重组,实现拥塞控制、网络互连等功能,该层数据以IP数据报(IP分组)的形式传输

  • 传输层: 负责向用户提供端到端的通信服务,实现流量控制以及差错控制,这一层主要重点是两个协议 : UDP 和 TCP

  • 应用层: 为应用程序提供了网络服务,应用层协议最著名的就是HTTP, FTP了, 还有一个重要的DNS

    二、TCP和UDP的区别

三 TCP的三次握手

  • 第一次握手:建立连接
  • 第二次握手:响应连接
  • 第三次握手:测试数据

本帖附件

点击下载

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

Source Insight快捷键大全

发表于 2019-12-06

Source Insight快捷键大全

退出程序 : Alt+F4

重画屏幕 : Ctrl+Alt+Space

完成语法 : Ctrl+E

复制一行 : Ctrl+K

恰好复制该位置右边的该行的字符 : Ctrl+Shift+K

复制到剪贴板 : Ctrl+Del

剪切一行 : Ctrl+U

剪切该位置右边的该行的字符 : Ctrl+;

剪切到剪贴板 : Ctrl+Shift+X

剪切一个字 : Ctrl+,

左边缩进 : F9

右边缩进 : F10

插入一行 : Ctrl+I

插入新行 : Ctrl+Enter

加入一行 : Ctrl+J

从剪切板粘贴 : Ctrl+Ins

粘贴一行 : Ctrl+P

重复上一个动作 : Ctrl+Y

重新编号 : Ctrl+R

重复输入 : Ctrl+

替换 : Ctrl+H

智能重命名 : Ctrl+’

关闭文件 : Ctrl+W

关闭所有文件 : Ctrl+Shift+W

新建 : Ctrl+N

转到下一个文件 : Ctrl+Shift+N

打开 : Ctrl+O

重新装载文件 : Ctrl+Shift+O

另存为 : Ctrl+Shift+S

显示文件状态 : Shift+F10

激活语法窗口 : Alt+L

回到该行的开始 : Home

回到选择的开始 : Ctrl+Alt+[

到块的下面 : Ctrl+Shift+]

到块的上面 : Ctrl+Shift+[

书签 : Ctrl+M

到文件底部 : Ctrl+End, Ctrl+(KeyPad) End

到窗口底部 : (KeyPad) End (小键盘的END)

到一行的尾部 : End

到选择部分的尾部 : Ctrl+Alt+]

到下一个函数 : 小键盘 +

上一个函数 : 小键盘 -

后退 : Alt+,, Thumb 1 Click

后退到索引 : Alt+M

向前 : Alt+., Thumb 2 Click

转到行 : F5, Ctrl+G

转到下一个修改 : Alt+(KeyPad) +

转到下一个链接 : Shift+F9, Ctrl+Shift+L

回到前一个修改 : Alt+(KeyPad) -

跳到连接(就是语法串口列表的地方) : Ctrl+L

跳到匹配 : Alt+]

下一页 : PgDn, (KeyPad) PgDn

上一页 : PgUp, (KeyPad) PgUp

向上滚动半屏 : Ctrl+PgDn, Ctrl+(KeyPad) PgDn, (KeyPad) *

向下滚动半屏 : Ctrl+PgUp, Ctrl+(KeyPad) PgUp, (KeyPad) /

左滚 : Alt+Left

向上滚动一行 : Alt+Down

向下滚动一行 : Alt+Up

右滚 : Alt+Right

选择一块 : Ctrl+-

选择当前位置的左边一个字符 : Shift+Left

选择当前位置右边一个字符 : Shift+Right

选择一行 : Shift+F6

从当前行其开始向下选择 : Shift+Down

从当前行其开始向上选择 : Shift+Up

选择上页 : Shift+PgDn, Shift+(KeyPad) PgDn

选择下页 : Shift+PgUp, Shift+(KeyPad) PgUp

选择句子(直到遇到一个 . 为止) : Shift+F7, Ctrl+.

从当前位置选择到文件结束 : Ctrl+Shift+End

从当前位置选择到行结束 : Shift+End

从当前位置选择到行的开始 : Shift+Home

从当前位置选择到文件顶部 : Ctrl+Shift+Home

选择一个单词 : Shift+F5

选择左边单词 : Ctrl+Shift+Left

选择右边单词 : Ctrl+Shift+Right

到文件顶部 : Ctrl+Home, Ctrl+(KeyPad) Home

到窗口顶部 : (KeyPad) Home

到单词左边(也就是到一个单词的开始) : Ctrl+Left

到单词右边(到该单词的结束) : Ctrl+Right

排列语法窗口(有三种排列方式分别按1,2,3次) : Alt+F7

移除文件 : Alt+Shift+R

同步文件 : Alt+Shift+S

增量搜索(当用Ctrl + F 搜索,然后按F12就会转到下一个匹配) : F12

替换文件 : Ctrl+Shift+H

向后搜索 : F3

在多个文件中搜索 : Ctrl+Shift+F

向前搜索 : F4

搜索选择的(比如选择了一个单词,shift+F4将搜索下一个) : Shift+F4

搜索 : Ctrl+F

浏览本地语法(弹出该文件语法列表窗口,如果你光标放到一个变量/函数等,那么列出本文件该变量/函数等的信息) : F8

浏览工程语法 : F7, Alt+G

跳到基本类型(即跳到原型) : Alt+0

跳到定义出(也就是声明) : Ctrl+=, Ctrl+L Click (select), Ctrl+Double L Click

检查引用 : Ctrl+/

语法信息(弹出该语法的信息) : Alt+/, Ctrl+R Click (select)

高亮当前单词 : Shift+F8

语法窗口(隐藏/显示语法窗口) : Alt+F8

关闭窗口 : Alt+F6, Ctrl+F4

最后一个窗口 : Ctrl+Tab, Ctrl+Shift+Tab

本帖附件

点击下载

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

linux下的线程与进程

发表于 2019-12-06

两种线程设计模型

  • 核心级线程设计模型:

    由操作系统内核实现, 特点是: 速度快 windows系统采用的是这种设计模型

    可以比喻为用自己的大脑控制自己十根手指头

  • 用户级线程设计模型:

    操作系统核外实现的线程模式, 特点是: 线程调度在核外 速度不如核内 Linux系统采用的是这种

​ 可以比喻为自己的十根手指头需要借助外力才能动

Linux系统下有真正意义的多线程么?

由上面Linux采用的线程设计模型可知,Linux系统并没有真正意义上的多线程

因此, Linux系统里处理多线程不如Windows强悍

Linux系统的两个线程库

  • LinuxThreads线程库
  • RedHat的NPTL

这两个线程库实际上并没有完全按照线程模式进行实现

进程的生命周期

进程的创建及回收

在Android中, ActivityThead的创建预示着进程的创建

进程的级别(由高到低)

  • 前台进程: 优先级最高, 正处于Activity Resume()状态, 杀死前台进程需要用户响应
  • 可见进程
  • 服务进程
  • 后台进程
  • 空进程: 无组件启动,做进程缓存使用, 恢复速度快

当一个应用启动的时候, 它的进程级别不是保持固定的, Android内部通过Handler进行轮询检测当前进程的状态,ActivityThread掌控的Activity 的生命周期, 如果栈中无Activity存在, 但是有Service存在的情况下, 此时的进程级别就会从前台进程降为服务进程

如果想要查询当前进程的级别, 可以通过ActivityManager .RuningAppProcessInfo进行查询,内部有对应的变量和方法

进程级别的记忆方法

前见服后空

谐音: 权健服后空 (懂?)

本帖附件

点击下载

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

从源码角度分析Activity与Window及View之间的关系

发表于 2019-12-06

我们都知道布局文件的加载是在Activity的onCreate()方法中,使用setContentView进行加载

这个方法是个重载方法

它们无一例外都是使用的getWindow()进行加载

那么window是在什么时候创建的呢?

我们知道Acitivity的生命周期是从onCreate开始的, 其实在它之前还有一个方法已经被执行了, 那就是attach方法

PolicyManager创建了一个新的Window对象

接下来

我们进入到PolicyManager类中

IPolicy是个接口

我们需要找到它的实现类,通过寻找发现Pollicy.java实现了IPolicy接口

实现代码如下:

直接创建了一个PhoneWindow对象,

那么意味着 每创建一个Activity都会创建一个PhoneWindow对象

那么PhoneWindow与Window到底是什么关系呢?

PhoneWindow是Window的子类

那么到此为止, 我们知道了其实Activity中的setContentView实际上是PhoneWindow在处理

我们找到PhoneWindow.java能发现其对应的方法

这里面的是三个重载方法咱们一个一个来分析

首先第一个

咱们平常开发时在xml中写的布局并不是根结点, 而是contentParent的子view

总结

它们之间的关系可以大致理解为:

Activity: 相当于一栋房子

Window: 相当于房子里的一扇窗户

View: 相当于窗户上的一朵窗花

它们三个的创建顺序为:

Activity—>Window—>View

具体时序图如下:

本帖附件

点击下载

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

Android应用流程简介

发表于 2019-12-06

我们知道Android系统的启动是从Init.c开始

那么Android应用的启动过程是从哪里开始呢?

下面是具体的时序图参考:

从Launcher.java开始 由于虚拟机的特性每个应用都会独占一个进程,ActivityThead是应用启动的标志

本帖附件

点击下载

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

C++中类的构造函数和析构函数

发表于 2019-12-05

构造函数

对象创建的时候执行

1
student s //空参构造函数 栈内存中
1
student s("测试")//带参构造函数 栈内存中

或者

1
student *s=new student//空参构造函数 堆内存中
1
student *s=new student("测试")//带参构造函数 堆内存中

析构函数

对象销毁的时候执行

1
delete s

在构造函数中分配的堆内存空间需要在析构函数中进行释放

带参构造函数变量重名问题 使用关键字this解决

本帖附件

点击下载

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

Android系统的启动流程详解

发表于 2019-12-05

Android系统启动流程.

1.当系统引导程序启动Linux内核时, 内核会加载各种数据结构和驱动程序. 有了驱动之后, 开始启动Android系统并加载用户级别的第一个进程init(system/core/init/Init.c).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main(int argc, char **argv)
{
...

// 创建各种文件夹和挂载目录.
mkdir("/dev", 0755);

...

// 初始化日志.
log_init();

// 解析配置文件.
init_parse_config_file("/init.rc");

...

return 0;
}

2.加载Init.rc文件. 主要启动了一个Zygote(孵化器)进程, 此进程是Android系统启动关键服务的一个母进程.

1
2
3
4
5
6
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
socket zygote stream 666
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd

3.Zygote进程的初始化在App_main.cpp文件中开启, 代码片段如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main(int argc, const char* const argv[])
{
// 定义Android运行时环境.
AppRuntime runtime;
int i = runtime.addVmArguments(argc, argv);

...

bool startSystemServer = (i < argc) ?
strcmp(argv[i], "--start-system-server") == 0 : false;
setArgv0(argv0, "zygote");
set_process_name("zygote");

// 使用运行时环境启动Zygote的初始化类.
runtime.start("com.android.internal.os.ZygoteInit",
startSystemServer);

...
}

4.现在从c或c++代码进入到java代码中, ZygoteInit.java初始化类, 代码如下:

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
32
33
34
35
36
37
38
39
40
public static void main(String argv[]) {
// 加载系统运行依赖的class类.
preloadClasses();

...

if (argv[1].equals("true")) {
// Zygote孵化器进程开始孵化系统核心服务.
startSystemServer();
} else if (!argv[1].equals("false")) {
throw new RuntimeException(argv[0] + USAGE_STRING);
}

...
}

private static boolean startSystemServer()
throws MethodAndArgsCaller, RuntimeException {
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,3001,3002,3003",
"--capabilities=130104352,130104352",
"--runtime-init",
"--nice-name=system_server",
"com.android.server.SystemServer",
};

...

// 孵化器分叉开启SystemServer类, 并且把上面定义的参数.
// 传递给此类. 用于启动系统关键服务.
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids, debugFlags, null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);

...
}

5.Zygote进程分叉出SystemServer类, main函数如下:

1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String[] args) {
...

// 加载本地的动态链接库.
System.loadLibrary("android_servers");

// 调用动态链接库中的c函数.
init1(args);
}

// 这里init1的函数定义在frameworks\base\services\jni\com_android_server_SystemServer.cpp下的方法.
native public static void init1(String[] args);

6.comandroidserver_SystemServer.cpp的代码片段如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
static JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
// 把native方法init1, 映射到android_server_SystemServer_init1. (这里是定义的函数指针)
{ "init1", "([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1 },
};

static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
{
// 转调
system_init();
}

// 此方法没有方法体.
extern "C" int system_init();

7.system_init方法的方法体, 在System_init.cpp类中. 代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
extern "C" status_t system_init()
{
...

// 开启一些硬件相关的服务.
SensorService::instantiate();

...

// 获取Android运行时环境
AndroidRuntime* runtime = AndroidRuntime::getRuntime();

LOGI("System server: starting Android services.\n");
// 调用SystemServer类中静态方法init2. 从native层转到java层.
runtime->callStatic("com/android/server/SystemServer", "init2");

...
}

8.SystemServer下init2方法如下:

1
2
3
4
5
6
7
8
public static final void init2() {
Slog.i(TAG, "Entered the Android system server!");

// 进入Android系统服务的初始化.
Thread thr = new ServerThread();
thr.setName("android.server.ServerThread");
thr.start();
}

9.ServerThread中的run方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Override
public void run() {
...

// 初始化系统的服务, 并且把服务添加ServiceManager中, 便于以后系统进行统一管理.
ServiceManager.addService("entropy", new EntropyService());

...

// 调用了ActivityManagerService的systemReady的方法.
((ActivityManagerService)ActivityManagerNative.getDefault())
.systemReady(new Runnable() {
public void run() {
...
}
});

...
}

10.ActivityManagerService下的systemReady方法如下:

1
2
3
4
5
6
public void systemReady(final Runnable goingCallback) {
...

// 调用了ActivityStack中的resumeTopActivityLocked去启动Activity
mMainStack.resumeTopActivityLocked(null);
}

11.ActivityStack中的resumeTopActivityLocked方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
final boolean resumeTopActivityLocked(ActivityRecord prev) {
// 找到第一个当前没有关闭的Activity, 系统刚刚系统没有任何Activity执行, 所以next为null
ActivityRecord next = topRunningActivityLocked(null);

// Remember how we'll process this pause/resume situation, and ensure
// that the state is reset however we wind up proceeding.
final boolean userLeaving = mUserLeaving;
mUserLeaving = false;

if (next == null) {
// There are no more activities! Let's just start up the
// Launcher...
if (mMainStack) {
// 开启Launcher应用的第一个Activity界面.
return mService.startHomeActivityLocked();
}
}
}

12.home界面显示, 这时Android系统启动完毕. 进入到待机画面.

本帖附件

点击下载

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

Source Insignt4.0的基本使用

发表于 2019-12-05

第一步 创建新工程

选择默认配置即可

第二步 加载源码文件

这里有三个Add选项

  • Add : 添加指定文件
  • Add All: 将选中目录的所有文件加入到工程中
  • Add Tree: 递归加入所有文件,它采用了部分打开文件的方式,没有用到的文件不会打开,所以,加入数千个文件也不用担心加入的文件超出程序的所能容忍的最大值 推荐使用这种

源码加载完成后关闭该窗口

第三步 熟悉主界面和源码搜索

第四步 更改字体大小

面板字体设置

代码显示窗口字体设置

常用快捷键介绍

各工具栏命令如下:

img对应的文件菜单的功能

New(快捷键ctrl+N) 新建一个文件

Open(快捷键ctrl+O) 打开一个文件

Save(快捷键ctrl+S) 保存当前打开的文件

Save As(快捷键ctrl+shift+S) 将当前打开的文件保存为其它名子的文件

Save All(快捷键ctrl+A) 保存所有打开的和修改过的文件

Print 打印当前打开的文件

img对应的编辑菜单功能

Cut(快捷键ctrl+X)

Copy(快捷键ctrl+C)

Paste(快捷键ctrl+V)

Undo(快捷键ctrl+Z)

Redo(快捷键ctrl+Y)

img对应查找菜单功能

Search(快捷键ctrl+F) 在当前打开的文件中查找

Search Backward(快捷键F3) 在当前光标位置进行向后查找

Search Forward(快捷键F4) 在当前光标位置进行向前查找

Search Files(快捷键ctrl+shift+F) 在多文件(Source Insight工程中)中查找

Replace(快捷键ctrl+H) 在当前文件中进行查找和替代

img

对应于窗口功能,与普通的多文档编辑器相同,用来设置打开多个文件时窗口显示方式和规则。

img

用来设置Project窗口、Context窗口、Relation窗口和Clip窗口的显示或关闭。当快捷键点亮时,所对应的窗口显示。

img

Jump To Definition(快捷键ctrl+=) 跳转到当前光标所在位置的函数或变量的定义处(并打开文件)

Symbol Info 弹出一个窗口来显示当前光标位置的函数或变量的定义原型

Browse Project Symbols(快捷键F7) 在整个工程中查找一个函数或变量的出现位置

Lookup Reference(快捷键ctrl+/) 建立一个Reference链接,所对应的链接处会出现一个链接标志,通过链接标志可以方便的进行函数的查看。

img

Go To Previous Link 跳转到前一个Reference链接(此功能必须先建立一个Reference链接)

Go To Next Link(shift+F9) 跳转到前一个Reference链接(同上)

Go Back(Alt+)) 光标调转到前一个历史操作位置

Go Forward(Alt+.) 光标调转到后一个历史操作位置

Go To Line(F5) 跳转到指定的行位置

Bookmark(ctrl+M) 书签

img

帮助功能

本帖附件

点击下载

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

Android系统架构简介

发表于 2019-12-05

Android系统架构师安卓系统的体系机构,Android的系统架构和其他操作系统一样,采用了分层的架构,共分为4层,从高到低分别是Android应用层,Android应用架构层,Android系统运行层和Linux内核层。

1. 应用程序

顶层中有所有的Android应用程序,包括通讯录、浏览器等,你写的应用程序也被安装在这层;所有的的应用程序都是使用Java语言编写的。

2. 应用框架层

这一层主要提供构建应用程序是可能用到的各种API,Android自带的一些核心应用就是使用这些API完成的,开发者也可以通过使用API来构建自己的应用程序

活动管理者(Activity Manager):控制应用程序生命周期和活动栈的所有方面

内容提供器(Content Providers):允许程序之间发布和分享数据。

资源管理器(Resource Manager):提供对非代码嵌入资源的访问,如字符串、颜色设置和用户界面布局。

通知管理器(Notification Manager):允许应用程序显示对话框或者通知给用户

视图系统(View System):一个可拓展的视图集合,用于创建应用程序用户界面

3. 系统运行库层

1) 程序库

Android包含一些C/C++库,这些库能被Android系统中不同的组件使用。他们通过Android应用程序框架为开发者提供服务,以下是一些核心库:

  • 系统C库(libc):一个从BSD继承来的标准C系统函数库,他是专门为基于embedded linux的设备定制的媒体库(Media Framework):基于Packet Video opencore; 该库支持多种常用的音频、视频格式回放和录制,同时支持静态图像文件。编码格式包括 MPEG4。H264、MP3、AAC、AMR、JPG、PNG。
  • Surface Manager:对显示子系统的管理,并且为多个应用程序提供了2D和3D图层的无缝融合。
  • SGL:底层的2D图形引擎
  • 3D libraries:基于OpenFLES1.0 APLs实现,该库可以使用硬件3D加速或者使用高度优化3D软加速
  • FreeType:位图(bitmap)和矢量(vector)字体显示
  • SQLite:一个对于所有应用程序可用,功能强劲的轻型关系型数据库引擎。

2) Android运行库

Android包括了一个核心库,该核心库提供了Java编程语言核心库的大多数功能。

每一个Android应用程序都在它自己的进程中运行,都拥有一个独立的Dalvik虚拟机实例。Dalvik被设计成一个设备可以同时高效地运行多个虚拟系统。Dalvik虚拟机执行(.dex)的Dalvik可执行文件,该个税文件针对小内存使用做了优化。同时虚拟机是基于寄存器的,所有的类都经由java编译器编译,然后通过SDK中的”dx”工具转化成 .dex格式由虚拟机执行

Dalvik虚拟机依赖于linux内核的一些功能,比如线程机制和底层内存管理机制。

4. Linux内核层

Android系统基于Linux2.6内核,这一层为Android设备各种硬件提供了底层驱动,如显示驱动,音频驱动,照相机驱动,蓝牙驱动,WIFI驱动,电源管理等

区别DVM与JVM

  1. 首要差别

1Dalvik:基于寄存器,编译和运行都会更快些

JVM:基于栈,编译和运行都会慢一些

  1. 字节码的区别

Dalvik:执行.dex格式的字节码,是对.class文件进行压缩后产生的,文件变小

JVM:执行.class格式的字节码

  1. 运行环境的区别

Dalvik: 一个应用启动都运行一个单独的虚拟机运行在一个单独的进程中

JVM:只能运行一个实例,也就是所有应用都运行在同一个JVM中

本帖附件

点击下载

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

1…474849…51

乱码三千

android程序员一枚,擅长java,kotlin,python,金融投资,欢迎交流~

505 日志
145 标签
RSS
© 2026 乱码三千
本站总访问量次
由 Hexo 强力驱动
|
主题 — NexT.Muse v5.1.4
0%