zoukankan      html  css  js  c++  java
  • 深入理解HelloWorld

             Hello World几乎是是每一门编程语言的第一个节课  现在到已然成为一种传统

            JAVA把C和C++的复杂语法以及容易造成编程错误的指针手动释放内存等弊端给屏蔽了  C和C++是直接和操作系统直接交互  会造成忘记释放内存的错误  JAVA则依赖于JVM(Java Virtual Machine <Java虚拟机>)管理  JAVA通过JVM和操作系统打交道   出错JVM会报异常error  还有垃圾回收器等 能够自动帮你释放内存  还解决了跨平台问题

             我们写好Hello World后  通过调用JDK的工具后   编译成了.class文件  此时会在内存中划分一段空间  创建一个JVM  通过类加载器校验class文件是否符合JVM的规范  JVM在对Java类解释执行

    调用JDK的工具javac变成class文件这一步与JVM无关
    编译 即把我们写好的java文件 通过javac命令编译成字节码 也就是我们常说的.class文件
    运行 则是把编译生成的.class文件交给JVM执行
    1 public class Hello{
    2         public static  void main(String[] args){
    System.out.printf("Hello"); 5 } 6 }
    JVM在将类字节码读入到内存中后 会找到加载类中的主类 在主类中找到main方法之后在执行main方法然后输出Hello
    为了JVM的安全性class文件在加载时在类加载器中会经历这么几个步骤
      
    Java类从被虚拟机加载开始 到卸载出内存为止 它的整个生命周期包括 加载(Loading) 验证(Verification) 准备(Preparation) 解析(Resolution) 初始化(Initialization) 使用(Using)和卸载(Unloading)7个阶段 其中验证 准备和解析又统称为连接(Linking)阶段
    加载 将class文件加载到内存中
    验证 两点 验证当前class文件的是否兼容当前JVM的版本 验证class文件是否符合JVM规范(JVM规定class的第一个字节码必须有一个十六进制的魔数值)
    准备 将类成员初始化为初始值 final变量直接初始化为变量值
    解析 将符号引用解析为直接引用(直接引用即为内存地址 如 0x000000001)
    初始化 把定义的static变量或者static代码块按顺序组织成(clinit)构造器也成为类成员构造器来初始化变量
    卸载 当该类的class对象不再被引用之后 该类的生命周期也就结束了 之后 该类会被类加载器卸载
     
    Hello.java通过javac变成Hello.class文件变成java文件后经过类加载器的几个阶段 就会把信息放在jvm的方法区里面 关于所有类的信息通过常量池都会保存在方法区 生成了一个代表所有类信息的变量classInstance 变成字节码文件后 方法区里面就有它的信息 然后执行main方法就会把它压到线程栈里面 把system类加载到方法区里 system有个.out的静态对象 调用out对象的实例方法println输出hello 然后输出hello
     
    javap -c 将字节码反编译为字节码指令输出
    getstatic取得静态属性方法 system会加载到方法区在常量池保存着 从系统类中拿到一个属性out 压到栈底 #2是代表着2号常量池 从syteam的2号常量池(方法区中是一个个的常量池 每个类都有它的常量池) 在拿到string调用out方法的plintln 最后return
    我们在来看另外一段代码
    public class Heelo{
            public static  void main(String[] args){
               Hello hello = new Hello();
                 System.out.printf("Hello");
      }
    }
    
    变成字节码文件后 方法区里便会有关于类的所有信息 之后执行main方法便会压到线程栈里面执行main方法
    1)当执行中碰到new这个关键字后 那么main主线程便会在自己的线程栈中声明一个对象Hello hello(对象的声明)
    2)在jvm的堆内存空间中申请一片内存地址 之后将关于Hello类的相关信息如实例变量等加载到堆内存空间当中
    3)对象的声明即对象的引用指向堆内存中开辟的对象
    Hello hello(对象的声明) = new Hello(); (创建一个对象)
    堆内存当中创建对象的执行顺序:
    1)加载实例信息到到开辟的堆内存空间当中
    2)执行构造方法也就是<init>方法
    堆内存中开辟的对象结构:对象是由头部信息和实例信息构造 这里我们主要分析头部信息
    1)对其填充也就是偏移值 hotspot vm自动内存管理系统规定了对象的大小必须是8字节的整数倍 当实例对象数据没有对齐时 就需要对齐填充来补全
    2)持有指向方法区的指针 静态变量把实例方法的部分信息和类信息加载到堆内存空间里面
    3)描述信息
    持有当前对象锁的线程id和持有对象锁的线程个数
    在gc中存活的生命周期数
    偏向锁的标志 偏向锁 当线程对此对象上锁执行完毕后 如果下一次访问该对象的线程也是上一次的线程那么不对此线程重新上锁
  • 相关阅读:
    visual studio 2019 sql server localdb 数据库中文乱码解决方法
    Ado.net总结
    Ado.Net总结
    提升DataGridView加载速度的三个属性设置
    winform程序:newtonsoft json 序列化时出现 “unterminated string. Excepted delimiter..."
    entityframewor core 不让属性生成数据库的列
    在winform中屏蔽双击最大化或最小化窗体(C#实现),禁用任务管理器结束程序
    使用cefsharp在winform中嵌套浏览器
    PIE SDK算法的同步调用
    PIE SDK小波变换
  • 原文地址:https://www.cnblogs.com/daomeidan/p/12490407.html
Copyright © 2011-2022 走看看