java发布软件 java开发的软件怎么运行

java发布软件 java开发的软件怎么运行_JavaSE

简单介绍一下 Java 程序的运行流程和内存分析。
   


0 Java 简介

首先简单介绍一下 Java 的历史与 Java 的核心机制。

Java 的历史

Java 最初产生于 SUN 公司的 “Green” 小组,该小组由 James Gosling 领导,最初的名字叫 Oak,在发现该名称已被注册之后,改名为 java。从 1996 年 1 月到现在,Java 经历了不断的演变。1999 年 6 月,Java 体系被分为三个方向:J2ME(微型版,移动端)、J2SE(桌面版,桌面端) 和 J2EE(企业版,服务端)。如今 JavaSE 的长期支持版(LTS)已经发展到了 11 版。

Java 的核心机制

Java 的两个基本的核心机制分别是 Java 虚拟机(JVM)和 Java 的垃圾回收器(GC):

  1. JVM 可以理解为一个可运行 Java 字节码的虚拟计算机系统。正是 JVM 的存在使得 Java 语言具有了跨平台的特性,因为所有的 Java 原码都会被首先编译成 Java 字节码文件,从而交给 JVM 处理,而不直接与具体的操作系统通信。所以,对于不同的平台,有对应的不同的 JVM 来实现代码与平台的分离,从而实现了所谓的“一次编译,到处执行”。
  2. Java 中的 GC 负责自动回收 JVM 中不再使用的内存空间。GC 的垃圾回收工作不需要由外部干预,从而消除了程序员回收无用内存的责任(在C/C++ 中这个工作是需要程序员负责考虑的)。GC 是 JVM 提供的一种系统线程跟踪存储空间的分配情况,当 JVM 处于空闲时,它会检查并释放掉那些可以被释放的存储空间。GC 是无法被精准控制和干预的,在 Java 程序运行的过程中它是自主启动并运行的。

1 JDK、JRE和JVM之间的关系

  • JDK:Java Development Kit,Java 开发工具包 - 开发人员进行 Java 软件开发测试的一套工具
  • JRE:Java Runtime Environment,Java 运行时环境 - Java 软件成品运行所依赖的环境
  • JVM:Java Virtual Machine,Java 虚拟机 - Java 语言实现跨平台运行的一种软件
  • 三者的关系是:JDK包含JRE,JRE包含JVM,像下图这样。

java发布软件 java开发的软件怎么运行_字节码_02



2 Java 编译与运行过程


  • java程序的运行包括两个非常重要的阶段:编译阶段运行阶段。它们的大致过程如下图

java发布软件 java开发的软件怎么运行_字节码_03


  • 编译:
  • java 源文件通过 JDK 中的编译器 javac 通过的编译,编译操作方式如下:
    javac -encoding 编码方式 -d 输出为字节码文件的路径 代码(相对)路径
    如:
    javac -encoding utf8 -d ../out/ ./src/*.java,它表示以 utf-8 格式编码 ./src/ 路径下的所有 Java 源文件,生成的字节码文件放到上一级目录的 out/ 路径下。
  • 编译阶段的主要任务是检查 java 源程序语法,符合 java 语法规则能正常生成 字节码文件 xxx.class。字节码文件是只有 JVM 才能理解的文件,通过 JVM 解释为不同操作系统的可执行二进制机器码。字节码文件是程序最终执行需要的文件,而不是 java 源文件。字节码文件可以拷贝到任何操作系统中运行,实现跨平台的效果。
  • 一个 java 源文件可以生成多个字节码文件,每个字节码文件对应源文件中定义的一个类;
  • 运行:
  • 使用JDK自带的执行工具/命令(java.exe)运行程序:
    java 包名.类名
    如:
    java com.somedomain.util.DataMonitor,包名实际上已目录结构的形式存在,并且通常以反向域名的方式形成多级目录结构,比如这里对应的目录结构为 ./com/somedomain/util/,最后跟类名 DataMonitor,它必须是在指定包内(目录结构下)存在的可运行字节码文件(类中包含作为程序入口的 public static void main() 方法)。
  • 运行阶段过程:

    java.exe 启动 JVM,JVM启动类加载器(ClassLoader),类加载器在硬盘上搜索对应的字节码文件,将其装载到 JVM 当中,JVM 将字节码文件解释成二进制数据,操作系统执行二进制和底层硬件平台进行交互,完成相应程序效果。

3 程序运行过程的内存分析

  • JVM 内存空间主要分为三块(还有其他空间):方法区内存堆内存栈内存
  • 方法片段属于字节码文件的一部分,字节码文件在类加载时,将其放到了方法区中。所以,JVM中的三块主要内存空间中最先有数据的是方法区内存,其中存放了代码片段。代码片段在方法区内存中只有一份,可以被重复使用。
  • 方法只有在被调用时才会被动态地分配所属空间。每次调用都需要为该方法在栈内存中分配独立的运行空间,此时发生压栈动作。方法执行结束后,对应的内存空间会全部释放,此时发生弹栈动作。下面是示例代码和方法执行过程的内存变化图。


登录后复制

public class UserTest {
    public static void main(String[] args) {
        int i = 10;
        add(i); // 传递i中的字面值10
        System.out.println("value of i in main() is " + i); // 10
    }

    public static void add(int i) {
        i++;
        System.out.println("value of i in add() is " + i); // 11
    }
}

   
java发布软件 java开发的软件怎么运行_字节码_04


传递字面值

  • 运行阶段在方法体中声明的局部变量,在栈内存中为其分配空间。而局部变量的参数传递实际上是传递的参数地址中所存的内容,这个内容可以是字面值,也可以是对象地址 。
  • 字面值传递中,接收方参数(等号左边)的值被修改,而传递方参数(等号右边)的值不受影响。
  • 对象地址的传递中,由于两个参数保存的内容指向同一对象地址,因此两方的操作指向同一片内存空间。下面是相应示例代码和方法执行过程的内存变化图。


登录后复制

public class UserTest {
    public static void main(String[] args) {
        User u = new User("Tomas", 56);
        System.out.println(u.name+"'s age before add() is "+u.age); // 1
        add(u); // 传递u的内存地址
        System.out.println(u.name+"'s age after add() is "+u.age); // 10
    }

    public static void add(User u) {
        u.age ++;
        System.out.println(u.name+"'s age within add() is "+u.age);
    }
}

class User {
    String name;
    int age;
    public User(String n, int a) {
        name = n;
        age = a;
    }
}

   
java发布软件 java开发的软件怎么运行_java发布软件_05

传递对象地址


免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删

QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空