您的位置:首页 > 编程语言 > Java开发

CJ-概述与环境-运行机制与基本规则(gc)

2018-02-05 21:14 211 查看
程序运行机制

Java既具有解释型语言的特征,也具有编译型语言的特征,因为 Java程序要经过先编译,后解释两个步骤

高级语言的运行机制

计算机高级语言按程序的执行方式可以分为编译型和解释型

编译型使用专门的编译器,针对特定平台(操作系统)将某种高级语言源代码一次性“翻 译”成可被该平台硬件执行的机器码(包括机器指令和操作数),并包装成该平台所能识别的可执行性 程序的格式,这个转换过程称为编译(Compile)。编译生成的可执行性程序可以脱离开发环境,在特定 的平台上独立运行

有些程序编译结束后,还可能需要对其他编译好的目标代码进行链接,即组装两个以上的目标代码模块生成最终的可执行性程序,通过这种方式实现低层次的代码复用

编译型语言一次性地编译成机器码,所以可脱离开发环境独立运行,而且通常运行效率较高

编译型语言的程序被编译成特定平台上的机器码,因此编译生成的可执行性程序通常无法移 植到其他平台上运行

如需移植,则必须将源代码复制到特定平台上,针对平台进行修改,至少也需要采用特定平台上的编译器重新编译(c/c++)

解释型语言使用专门的解释器对源程序逐行解释成特定平台的机器码并立即执行的语言。解释型语言通常不会进行整体性的编译和链接处理,解释型语言相当于把编译型语言中的编译和解释过程混合到一起同时完成

可认为:每次执行解释型语言的程序都需要进行一次编译,因此解释型语言的程序运行效率通常 较低,而且不能脱离解释器独立运行

优势:跨平台比较容易,只需提供特定平台的解释器即可,每个特定平台上的解释器负责将源程序解释成特定平台的机器指令即可

解释型语言方便地实现源程序级的移植,但这是以牺牲程序执行效率为代价的(python Ruby)

伪编译型语言,如 Visual Basic,它属于半编译型语言,并不是真正的编译型 语言。它首先被编译成P-代码,并将解释引擎封装在可执行性程序内

Java程序的运行机制和JVM

Java语言编写的程序需要经过编译步骤,编译步骤并不会生成特定平台的机器码,而是生成一种与平台无关的字节码(也就是*.class文件)。当然,这种字节码不是可执行性的,必须使用Java解释器来解释执行,所以既是编译型语言,也是解释型语,不纯粹编译型

Java负责解释执行字节码文件的是Java虚拟机JVM (Java Virtual Machine)

JVM是可运行Java字节码文件的虚拟计算机。所有平台的JVM向编译器提供相同的编程接口,而编译器只需要面向虚拟机,生成虚拟机能理解的代码,然后由虚拟机来解释执行

使用Java编译器编译Java程序时,生成的是与平台无关的字节码,这些字节码不面向任何具体平台,只面向JVM。不同平台上的JVM都是不同的,但它们都提供了相同的接口。JVM是 Java程序 跨平台的关键部分,只要为不同平台实现了相应的虚拟机,编译后的Java字节码就可以在该平台上运行。相同的字节码程序需要在不同的平台上运行,只能通过中间的转换器,JVM就是这个转换器。

JVM是一个抽象的计算机,和实际的计算机一样,它具有指令集并使用不同的存储区域。它负责 执行指令,还要管理数据、内存和寄存器

Oracle制定的Java虚拟机规范在技术上规定了 JVM的统一标准最终实现平台无关性,具体如下:

指令集

寄存器

类文件的格式



垃圾回收堆

存储区

JDK的全称是Java SE Development Kit,即 Java标准版开发包

Java运行时环境,它的全称是Java Runtime Environment,因此也被称为JRE

JRE包舍JVM。JVM是java运行的核心虚拟机,JRE还包括其他需要的基础类库、字节码校验器、类加载器等

javac -d destdir srcFile
-d destdir用以指定编译生成的字节码文件的存放路径
srcFile是Java源文件所在的位置
通常将生成的字节码文件放在当前路径下,当前路径可以用一点(.)来表示
javac -d . HelloWorld.java
-d省略文件存在当前目录下,一个java文件里面有多少个类编译时就会生成多少个.class文件

java执行


Java程序的组织形式

面向对象的程序设计语言, 必须以类 (class)的形式存在, 类(class)是 Java程序的最小程序单位。Java程序不允许可执行性语句、方法等成分独立存在,所有的程序部分都必须放在类定义里

java解释器规定:如需某个类能被解释器直接解释执行,则这个类里必须包含main方法,而 且 main

方法必须使用public static void来修饰,且 main方法的形参必须是字符串数组类型(String[] args是字

符串数组的形式)。也就是说,main方法的写法几乎是固定的

Java虚拟机就从这个main方法开始解 释执行,因此,main方法是Java程序的入口

对于不包含main方法的类,也是有用的类。对于一个大型的Java程序而言,往往只需要一个 入口,而其他类都是用于被main方法直接或间接调用的

Java程序源文件的文件名必须与public类的类名相同,因此,一个Java源文件里最多只能定

义一个public类

一个Java源文件可以包含多个类定义,但最多只能包含一个public类定义

Java语言是严格区分大小写的语言

main方法的问题

main方法必须 使用public和 static来修饰,必须使用void声明该方法的返回值,而且该方法的参数类型只能是一个字 符串数组,而不能是其他形式的参数

Java虚拟机只会选择从main方法开始执

垃圾回收机制

显式垃圾 回收主要有如下两个缺点

程序忘记及时回收无用内存,从而导致内存泄漏,降低系统性能。

程序错误地回收程序核心类库的内存,从而导致系统崩溃

Java程序的内存分配和回收都是由 JRE在后台自动进行的,这种机制被称为垃圾回收(Garbage Collection, GC)。通常JRE会提供一个后台线程来进行检测和控制,一般都是在CPU空闲或内存不足吋自动进行垃圾回收,而程序员无法精确控制垃圾回收的时间和顺序等

Java的堆内存是一个运行时数据区,用以保存类的实例(对象),Java虚拟机的堆内存中存储着正 在运行的应用程序所建立的所有对象,这些对象不需要程序通过代码来显式地释放。一般来说,堆内存的回收由垃圾回收来负责,所有的JVM实现都有一个由垃圾回收器管理的堆内存

垃圾回收是一种动态存储管理技术,它自动释放不再被程序引用的对象,按照特定的垃圾回收算法来实现内存资源的自动回收功能

Java中,当没有引用变量指向原先分配给某个对象的内存时,该内存便成为垃圾。JVM的一个超级线程会自动释放该内存区垃圾回收意味着程序不再需要的对象是“垃圾信息”,这些信息将被丢弃垃圾回收也可以清除内存记录碎片。由于创建对象和垃圾回收器释放丢弃对象所占 的内存空间,内存会出现碎片。碎片是分配给对象的内存块之间的空闲内存区,碎片整理将所占用的堆 内存移到堆的一端,JVM将整理出的内存分配给新的对象。

垃圾回收能自动释放内存空间,减轻编程的负担。这使Java虚拟机具有两个显著的优点。垃圾回收机制可以很好地提高编程效率

任何一种垃圾回收算法一般要做两件基本的事情:发现无用的对象;回收被无用对象
4000
占用的内存空间,使该空间可被程序再次使用

垃圾回收具有如下几个特点。

垃圾回收机制目标是回收无用对象的内存空间,这些内存空间都是JVM堆内存里的内存空间,垃圾回收只能回收内存资源,对其他物理资源,如数据库连接、磁盘I/O等资源则无能为力

为了更快地让垃圾回收机制回收那些不再使用的对象,可以将该对象的引用变量设置为null, 通过这种方式暗示垃圾回收机制可以回收该对象。垃圾回收发生的不可预知性。由于不同jvm 采用了不同的垃圾回收机制和不同的垃圾回收算 法,因此它有可能是定时发生的,有可能是当CPU空闲时发生的,内存消耗出现极限时发生

可以通过调用Runtime对象的gc()或 System.gc()等方法来建议系统进行垃圾回收

垃圾回收的精确性主要包括两个方面:

垃圾回收机制能够精确地标记活着的对象

垃圾回收器能够精确地定位对象之间的引用关系

前者是完全回收所有废弃对象的前提,否则就可能造成内存泄漏;而后者则是实现归并和复制等算法的必要条件,通过这种引用关系,可以保证所有对象都能被可靠地回收,所有对象都能被重新分配,从而有效地减少内存碎片的产生

Java基本原则:对于不再需要的对象,不要引用它们。如果保持对这些对 象的引用,垃圾回收机制暂时不会回收该对象,则会导致系统可用内存越来越少;当系统可用内存越来 越少时,垃圾回收执行的频率就越来越高,从而导致系统的性能下降
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java