java知识总结——java平台与内存管理

说明

  本文仅仅为了博主面试时方便查阅与梳理相关知识,如果有错误与不到位的地方,欢迎大佬指点改正,谢谢!
  阅读书籍:《java程序员面试笔试宝典》

一、java是平台独立语言

  1、平台独立性语言
  平台独立性是指可以在一个平台上编写和编译程序,而在其他平台上运行。
  保证java具有平台独立性的机制为“中间码”和“java虚拟机”。java程序被编译后不是生成能在硬件平台上可执行的代码,而是生成了一个“中间码”。不同的硬件平台上会装有不同的JVM,由JVM负责把“中间码”翻译成硬件平台能执行的代码。
  由此可见,JVM不具有平台独立性,而是与硬件相关的
  2、解释执行的步骤
  解释执行过程分三步进行:代码的装入、代码的校验和代码的执行。装入代码的工作由“类加载器”完成。被装入的代码由字节码校验器进行检查。
  3、java字节码的执行方式
  分两种方式:即时编译方式与解释执行方式。
  即时编译方式指的是解释器先将字节码编译成机器码,然后再执行该机器码。
  解释执行方式指的是解释器通过每次解释并执行一小段代码来完成java字节码程序的所有操作。通常采用的是解释执行方式
  C/C++语言没有跨平台的特性,但是有更高的执行效率。

二、java平台与其他语言

  java平台是一个纯软件的平台,这个平台可以运行在一些基于硬件的平台之上。java平台主要包含两个模块:JVM与java API
  每当一个java程序运行时,都会有一个对应的JVM实例,只有当程序运行结束后,这个JVM才会退出。JVM实例通过调研类的main()方法来启动一个java程序,而这个main()方法必须是公有的、静态的且返回值为void的方法,该方法接收一个字符串数组的参数,只有同时满足这些条件才可以作为程序的入口。

三、JVM加载class文件的原理机制

  类(class)只有被加载到JVM中后才能运行。当运行指定程序时,JVM会将编译生成的.class文件按照需求和一定的规则加载到内存中,并组织成为一个完整的java应用程序。这个加载过程是由类加载器来完成的,具体来说,就是由ClassLoader和它的子类来实现的。类加载器本身也是一个类,其实质是把类文件从硬盘读取到内存中
  类的加载方式分为隐式加载和显式加载两种。
  隐式加载指的是程序在使用new等方式创建对象时,会隐式地调用类的加载器把对应的类加载到JVM中。
  显示加载指的是通过直接调用class.forName()方法来把所需的类加载到JVM中。
  任何一个工程项目都是由许多个类组成的,当程序启动时,只把需要的类加载到JVM中,其他类只有被使用到的时候才会被加载,采用这种方法,一方面可以加快加载速度,另外一方面可以节约程序运行过程中对内存的开销
  在java语言中,每个类或接口都对应一个.class文件,这些文件可以被看成一个个可以被动态加载的单元,因此当只有部分类被修改时,只需要重新编译变化的类即可,而不需要重新编译所有文件,因此加快了编译速度。
  在java语言中,类的加载是动态的,它并不会一次性地将所有类全部加载后再运行,而是保证程序运行的基础类完全加载到JVM中,至于其他类,则在需要时才加载。
  在java语言中,类可以分为三类:系统类、扩展类和自定义类。关系如下:
类加载的关系
  类加载通过委托的方式实现的。当有类需要被加载时,类加载器会请求父类来完成这个载入工作,父类会使用其自己的搜索路径来搜索需要被载入的类,如果搜索不到,才会由子类按照其搜索路径来搜索待加载的类。
  类加载的主要步骤(3步)
  1、装载。根据查找路径找到相对应的class文件,然后导入。
  2、链接。链接又可以分为3个小的步骤,如下:
    (1)检查。检查待加载的class文件的正确性。
    (2)准备。给类中的静态变量分配存储空间。
    (3)解析。将符号引用转换成直接引用。
  3、初识化。对静态变量和静态代码块执行初始化工作。

四、GC(垃圾回收)

  GC的作用是回收程序中不再使用的内存。
  垃圾回收器主要负责完成3项任务:分配内存、确保被引用对象的内存不被错误地回收以及回收不再被引用的对象的内存空间。
  垃圾回收器的存在一方面提高了开发人员的生产效率,另一方面保证了程序的稳定性。
  只要有一个以上的变量引用该对象,该对象就不会被垃圾回收。
  常用的垃圾回收算法
  1、引用计数算法
  引用计数作为一种简单但是效率较低的方法,其主要原理如下:在堆中对每个对象都有一个引用计数器;当对象被引用时,引用计数器加1;当引用被置为空或离开作用域时,引用计数减1.
  2、追踪回收算法
  追踪回收算法利用JVM维护的对象引用图,从根节点开始遍历对象的应用图,同时标记遍历到的对象。当遍历结束后,未被标记的对象就是目前已不被使用的对象,可以被回收了。
  3、压缩回收算法
  压缩回收算法的主要思路为:把堆中活动的对象移动到堆中一端,这样就会在堆中另外一端留出很大的一块空闲区域,相当于对堆中的碎片进行了处理。虽然这种方法可以大大简化消除堆碎片的工作,但是每次工作都会带来性能的损失。
  4、复制回收算法
  把堆分成两个大小相同的区域,在任何时刻,只有其中的一个区域被使用,直到这个区域的被消耗完为止,此时垃圾回收器会中断程序的执行,通过变量的方式把所有活动的对象复制到另外一个区域中,在复制的过程中它们是紧挨着布置的,从而可以消除内存碎片。当赋值过程结束后程序会接着运行,直到这块区域被使用完,然后再采用上面的方法继续进行垃圾回收。
  这个算法的优点是在进行垃圾回收的同时对对象的布置也进行了安排,从而消除了内存碎片。但是也付出了很高的代价:对于制定大小的堆来说,需要两倍大小的内存空间;同时由于在内存调整的过程中要中断当前执行的程序,从而降低了程序的执行效率。
  5、按代回收算法
  把堆分成两个或者多个子堆,每一个子堆被视为一代。算法在运行的过程中优先收集那些“年幼的”对象,如果一个对象经过多次收集仍然“存活”,那么就可以把这个对象转移到高一级的堆里,减少对其的扫描次数。

五、java中的内存泄漏

  1、概念
  内存泄漏是指一个不再被程序使用的对象或变量还在内存中占有存储空间。
  一般的,内存泄漏主要有两种情况:一是在堆中申请的空间没有被释放;二是对象已不再被使用,但还仍然在内存中保留着。java中的内存泄漏主要指的是第二种情况。
  2、引起内存泄漏的原因
  (1)静态集合类,这些类的实例生命周期与程序一致,在程序结束前不能被释放,从而造成内存泄漏。
  (2)各种连接,只有连接关闭后,垃圾回收器才会回收对应的对象。
  (3)监听器。在java语言中,往往会使用到监听器。通常一个应用中会用到多个监听器,但在释放对象的同时往往没有相应地删除监听器,这也可能导致内存泄漏。
  (4)变量不合理的作用域,一般而言,如果一个变量定义的的作用域大于其使用范围,很有可能会造成内存泄漏,另一方面如果没有及时地把对象设置为null,很有可能会导致内存泄漏的发生。
  (5)单例模式可能会造成内存泄漏

六、java中的堆和栈的区别

  基本数据类型的变量以及对象的引用变量,其内存都分配在栈上,变量出了作用域就会自动释放。
  引用类型的变量,其内存分配在堆上或者常量池中,需要通过new等方式进行创建。
  具体而言,栈内存主要用来存放基本数据类型与引用变量。栈内存的管理时通过压栈和弹栈操作来完成的,以栈帧为基本单位来管理程序的调用关系,每当有函数调用时,都会通过压栈方式创建新的栈帧,每当函数调用结束后都会通过弹栈的方式释放栈帧。
  堆内存用来存放运行时创建的对象。一般用new关键字创建出来的对象都存放在堆内存中。由于JVM是基于堆栈的虚拟机,每个java程序都运行在一个单独的JVM实例上,每一个实例唯一对应一个堆,一个java程序内的多个线程也就运行在同一个JVM实例上,因此这些线程之间会共享堆内存,因此,多线程在访问堆中的数据时需要对数据进行同步

  java中引用的用法
  在堆中产生了一个数组或对象后,还可以在栈中定义一个变量取值等于数组或对象在堆内存中的首地址,这个变量就成了数组或对象的引用变量。
  引用变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。

  堆和栈的功能与作用比较
  堆主要是用来存放对象的,栈主要是用来执行程序的。
  相对于堆,栈的存取速度更快,但栈的大小和生存期必须是确定的,因此缺乏一定的灵活性。而堆却可以在运行时动态的分配内存,生存期不用提前告诉编译器,但这也导致了其存取速度的缓慢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值