C 语言和 JAVA 的区别
- C语言考虑内存,JAVA 拥抱需求 为用户着想;
- 单文件的编译时间 java 比 C语言快;
- C语言可以直接操作内 存, java 不能直接操作;
- C语言可以封装动态库, java 不行;
- C语言的代码不容易跨平台, java 的代码容易跨平台;
- C语言有指针, java 没有指针;
- C语言可以直接操作串 口 , java 需要第三方jar包支持;
- C语言的线程更加灵活, java 的线程都已经封装好了 ;
- C语言做单独功能, 可以增加效率, java适用做web应用开发;
- lunix是C语言编写的, java 也是C语言编写的;
- JAVA做web开发的时候, 已经有很多成型的框架技术, C语言很少, 且需要处理底层内容, 对应不熟悉计算机原理的开发者难度很大;
- JAVA的开源包太多了 , C语言也有但是偏少, 而且面向某个业务应用领域的框架没java多;
JAVA 优点
- 简单
- 风格类似于C++
- 摒弃了C++中容易引发程序错误的地方
- 面向对象
- 支持静态和动态风格的代码继承及重用
- 多线程
- 健壮
- 结构中立跨平台
- 安全
- 一次编写到处运行
JAVA 先编译后解释
- 按照 JVM 的语法规范 编译成虚拟机可以接受的统一标准的字节码文件。
- 不同系统对应的 JVM 将字节码文件解释成系统所要求的可执行的指令。
- JAVA 运行一定要有虚拟机。
JAVA 虚拟机 (JVM)
Java虚拟机(JVM) 是 Java Virtual Machine 的缩写, 它是一个虚构出来的计算机, 是通过在实际的计算机上仿真模拟各种计算机功能模拟来实现的。
JAVA中, 类加载器把一个类装入JAVA虚拟机需要经过三个步骤来完成: 装载、 链接、 初始化, 其中链接又分为校验、 准备、 解析过程
装载: 查找和导入. class文件
链接: 检查装入. class文件的正确性, 然后, java虚拟机为变量分配内存, 设置默认值
验证:确定类型符合 JAVA 语言的语义 [如 final 类不能有子类, final 类不能被覆盖],确保在类型和超类型之间没有不兼容的方法声明。
准备:JAVA 虚拟机为类变量分配内存,设置默认值 [String 为 null, int 为 0]。
解析:在类型的常量池中寻找类、接口,字段和方法的符合引用,把这些符号引用替换成直接引用的过程。
初始化: 把符号引用变成直接引用。
JAVA 内存分配
JAVA 的 JVM 的内存可分为3个区: 堆(heap)、栈(stack) 和方法区(method)
堆区:
- 存储对象, 每个对象都包含一个与之对应的class的信息 (class的目的是得到操作指令)
- JVM 只有一个堆区(heap)被所有线程共享, 堆中不存放基本类型和对象引用, 只存放对象本身。
- 对象属性空间 [根据属性的类型开辟空间]
- 对象方法空间 [存放的是方法区共享代码段的实例方法的地址引用 不是真正的方法代码]
栈区:
- 每个线程包含一个栈区 [以线程来划分方法栈] ,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象), 对象都存放在堆区中
- 每个栈中的数据(原始类型和对象引用 )都是私有的, 其他栈不能访问。
- 栈分为3个部分: 基本类型变量区、 执行环境上下文、 操作指令区(存放操作指令)。
- 栈中的每一个元素被称为栈帧, 每当线程调用一个方法的时候就会向方法栈压入一个新帧。 这里的帧用来存储方法的参数/形参、 堆空间的地址及其方法区的地址、 局部变量和运算过程中的临时数据/断点。
- [先进后出]方法执行完 栈空间释放销毁 main 在栈底
方法区:
- 代码区 [类代码区:定义的类和标准类库的类] [共享代码区]
- 数据区 [静态数据区:一加载就与类静态绑定] [常数据区:即常量池 String Integer]
- 又叫静态区, 跟堆一样, 被所有的线程共享。 方法区包含所有的class和static变量。
- 方法区中包含的都是在整个程序中永远唯一的元素, 如class, static变量。
JAVA 内存回收
- 内存分配和内存回收都是由虚拟机自动完成。
- 当一个对象失去引用的时候,虚拟机的垃圾回收机制会自动清除它,并回收它所占的空间
- 程序运行过程中会不断分配内存空间,那些不再使用的内存空间应该被即时回收,从而保证系统可以再次使用这些内存。若存在无用的内存没有被回收,则是内存泄漏。
- 垃圾回收机制:跟踪并监控每个 JAVA 对象,当某个对象处于不可达状态时,回收该对象所占用的内存清理内存分配,回收过程中产生的内存碎片。
JAVA 结构
- Java源程序基本组成单位为类
- 一个源程序可以有多个类,只能有一个主类,标识为public
- 主类类名作为文件名,又是编译器javac的入口
- 虚拟机执行的是字节码文件「.class文件」 这个字节码文件中必须有主方法 主方法「main」是虚拟机 JVM 的入口方法
- 编译特点:每一个类编译成独立的字节码文件 有几个类就有几个字节码文件
- 编译器识别主类 虚拟机识别主方法 所以主方法不一定要在主类中
JAVA 内存管理小技巧
- 尽量使用直接量, 少 new 对象。
- 使用 StringBuilder 和 StringBuffer进行字符串连接。
- 尽早释放无用对象的引用。
- 尽量少使用静态变量。
- 避免经常调用的犯法,循环中创建 JAVA 对象。
- 缓存经常使用对象 [用缓存池],最常见缓存就是数据连接池。
实现缓存的方式:使用 HashMap 进行缓存。
直接使用某些开源的缓存项目。
缓存是一种以牺牲系统空间来换取运行时间的技术。
- 尽量不要使用 finalize 。
- 考虑使用 SoftReference 。
创建很大的数组的时候,考虑用它来包装数组对象,同时因为可能会变成null ,所以应该显示的判断获取的对象是否为null,如果为null,重新加载这个对象。