11 java语言执行浅析1

article/2025/8/20 8:27:48

Java 是基于线程模型的语言,程序的执行是通过线程来调度和运行的。


一、Java 的最小执行单元:线程(Thread)

  • 每个 Java 程序至少有一个主线程(main thread),它从 main() 方法开始执行。
  • 所有代码最终都在线程中运行,包括方法调用、对象创建等操作。
  • 可以通过继承 Thread 类或实现 Runnable 接口创建多线程程序。
public class MyThread extends Thread {public void run() {System.out.println("Thread is running");}public static void main(String[] args) {MyThread t = new MyThread();t.start(); // 启动线程}
}

 结论:线程才是 Java 的最小执行单元;方法只是逻辑组织单位,并不能独立执行。


Java 与 Go 的面向对象/结构化设计差异 

Java:一切必须封装在类中(OOP)

  • Java 是一门典型的 面向对象编程语言(OOP)
  • 所有代码都必须写在类(class)内部,包括方法、变量、静态块等。
  • 没有“函数”这个一级类型,只有类中的方法。即使是一个简单的 main() 方法也必须定义在一个类里。
特点:
  • 强调封装性、模块性和可扩展性;
  • 更适合大型企业级应用开发;
  • 支持继承、多态、接口等 OOP 高级特性。
  • (X)灵活性略差,语法繁琐;
  • (X)对于简单脚本或小型项目不够轻便。

 Go:函数是一等公民,支持自由函数(FP + OOP)

  • Go 是一种 过程式 + 接口 + 并发模型 的语言,强调简洁和高效。
  • 函数是“一等公民”,可以直接定义并作为参数传递。
  • Go 中的函数可以独立存在,不依赖类结构。
  • 类型系统简单,没有继承,而是通过组合实现复用。
特点:
  • 更加灵活,适合并发、网络服务等场景;
  • 语法简洁,学习成本低;
  • 内置 goroutine 和 channel 支持 CSP 并发模型。
  • (X)缺乏传统 OOP 的继承机制;
  • (X)不适合构建复杂的类层次结构。

我们可以从 Java 的 动态代理(Dynamic Proxy) 和 Go 的 高阶函数(Higher-order Function) 来对比说明。

Java 动态代理基于 JVM 提供的 Proxy 类和 InvocationHandler 接口

public interface Service {void doSomething();
}public class RealService implements Service {public void doSomething() {System.out.println("Doing something...");}
}public class LoggingInvocationHandler implements InvocationHandler {private Object target;public LoggingInvocationHandler(Object target) {this.target = target;}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("Before method call");Object result = method.invoke(target, args);System.out.println("After method call");return result;}
}// 使用示例
Service realService = new RealService();
Service proxy = (Service) Proxy.newProxyInstance(realService.getClass().getClassLoader(),new Class<?>[]{Service.class},new LoggingInvocationHandler(realService)
);proxy.doSomething();
  • 动态代理本质上是 对方法调用的拦截与增强
  • 它并不是直接“传入一个函数,返回一个增强函数”,而是 对对象的方法调用做拦截处理
  • 但其背后的思想确实是:传入一个行为(目标对象),返回一个包装后的行为(代理对象)

Go 语言的“函数增强”方式:高阶函数

Go 没有动态代理的概念,但它可以通过 函数闭包 + 高阶函数 轻松实现类似功能。

package mainimport ("fmt""time"
)// 增强器函数:接收一个函数,返回一个新的增强函数
func timeLogger(fn func()) func() {return func() {start := time.Now()fn()fmt.Printf("Function took %v\n", time.Since(start))}
}func sayHello() {fmt.Println("Hello, World!")
}func main() {wrapped := timeLogger(sayHello)wrapped()
}
  • 直接操作函数,不需要类、接口、代理;
  • 更加轻量、直观;
  • 更容易写出通用中间件(如 HTTP Middleware);

Java 代码执行流程详解

1. Java 内存由 JVM 管理,主要分为以下区域:

1. 堆(Heap)
  • 所有对象实例和数组存储在此,是 JVM 管理的最大内存区域。
  • 线程共享,垃圾回收(GC)的主要区域。
  • 分代设计
    • 新生代(Young Generation):新创建的对象在此,分为 Eden 区和两个 Survivor 区。
    • 老年代(Old Generation):长期存活的对象(多次 GC 后仍存活)进入老年代。
    • 永久代 / 元空间(PermGen/Metaspace):JDK 8 之前存储类元数据(如类结构、方法字节码),JDK 8 后改为元空间(直接内存)。
2. 栈(Stack)
  • 线程私有,每个线程有独立的栈。
  • 存储局部变量方法调用帧(包含方法参数、返回值、局部变量表、操作数栈等)。
  • 栈帧(Stack Frame):每个方法调用创建一个栈帧,方法执行完毕后栈帧弹出。
3. 方法区(Method Area)
  • 线程共享,存储类的结构信息(如类名、字段、方法、常量池)。
  • JDK 8 之前是堆的永久代(PermGen),JDK 8 后改为元空间(Metaspace),使用直接内存。
4. 本地方法栈(Native Method Stack)
  • 为 ** 本地方法(如native关键字修饰的方法)** 服务,与 Java 栈类似。
5. 程序计数器(Program Counter Register)
  • 线程私有,记录当前线程执行的字节码行号,用于线程切换后恢复执行位置。

2. 程序启动:从 main() 方法开始

  • JVM 调用 main() 方法作为程序入口。
  • main() 方法本身是在主线程中执行的。
public static void main(String[] args) {System.out.println("Start of program");someMethod();System.out.println("End of program");
}

3. 方法调用栈(Call Stack)

  • Java 使用 调用栈(call stack) 来管理方法调用。
  • 每次调用一个方法,JVM 都会在当前线程的栈中压入一个 栈帧(Stack Frame)
  • 栈帧包含局部变量表、操作数栈、动态链接、返回地址等信息。
void methodA() {methodB();
}void methodB() {int x = 10;
}

调用顺序如下:

main()
└─ methodA()└─ methodB()
  • methodB() 执行完后,弹出栈帧;
  • 返回到 methodA()
  • 最终回到 main(),继续执行后续代码。

4. 异常处理与 finally 块

  • 即使发生异常,JVM 也会确保栈帧被正确弹出。
  • finally 块保证无论是否抛出异常都会执行(除非虚拟机退出)。

    5. 对象创建与内存分配示例

    public class MemoryExample {public static void main(String[] args) {// 1. 基本类型变量存储在栈中int a = 10;// 2. 对象引用存储在栈中,对象实例存储在堆中Person p = new Person("Alice", 25);// 3. 调用方法时,方法帧入栈p.sayHello();}
    }class Person {private String name;  // 成员变量存储在堆中的对象实例中private int age;      // 成员变量存储在堆中的对象实例中public Person(String name, int age) {this.name = name;this.age = age;}public void sayHello() {// 局部变量存储在栈帧中String message = "Hello, my name is " + name;System.out.println(message);}
    }
    
    内存分析:
    1. 基本类型变量a:存储在main方法的栈帧中。
    2. 对象引用p:存储在main方法的栈帧中,指向堆中的Person对象实例。
    3. Person对象实例:存储在堆中,包含nameage字段。
    4. 方法调用p.sayHello():创建新的栈帧,存储局部变量message,方法执行完毕后栈帧销毁。


    Java 垃圾回收机制(GC)与内存释放

    java -XX:+PrintCommandLineFlags -version

    此命令会输出 JVM 的版本信息和启动参数,其中启动参数里就包含了选用的垃圾收集器等关键信息。

    在Java 8中,默认的垃圾收集器配置是使用Parallel GC,即新生代采用Parallel Scavenge收集器,而老年代则使用Parallel Old收集器。这种组合旨在提高应用程序的整体吞吐量。

    从Java 9开始,JVM默认使用的垃圾收集器变更为G1(Garbage First)收集器,它被设计为能够处理非常大的堆,并且可以在大多数情况下提供更短的停顿时间。G1收集器通过将堆划分为多个区域(Region),然后根据垃圾的数量优先回收那些包含最多可回收对象的区域,从而实现高效内存管理。

    对于之后的版本,例如Java 11和Java 17等长期支持(LTS)版本,默认依旧是G1收集器。不过,值得注意的是,在较新的Java版本中(比如Java 17或更新版本),随着ZGC和Shenandoah等低延迟垃圾收集器的发展和完善,用户可以根据需要选择这些先进的垃圾收集器作为替代方案,但它们并不是默认选项。

    1. Java 内存模型简述

    区域描述
    方法区存储类信息、静态变量、常量池等
    堆(Heap)对象实例主要存放地,GC 主要工作区域
    每个线程私有,存储局部变量、方法参数等
    本地方法栈用于 Native 方法调用
    程序计数器当前线程所执行字节码的行号指示器

    2. 垃圾回收的基本原理

    • Java 的垃圾回收(Garbage Collection, GC)自动管理堆内存。
    • 可达性分析算法(GC Roots Tracing) 是主流判断对象是否为垃圾的方式:
      • 从 GC Roots 开始遍历引用链;
      • 无法到达的对象被视为不可达,可被回收。

    常见的 GC Roots 包括:

    • 虚拟机栈中的局部变量引用;
    • 方法区中类的静态属性引用;
    • 方法区中常量引用;
    • 本地方法栈中 Native 引用。

    3. 方法执行结束后是否会释放内存?

     局部变量(基本类型):
    • 存储在栈中,方法执行完毕自动弹出栈帧,无需 GC。
     局部变量引用的对象(如 new Object()):
    • 实际对象在堆中;
    • 方法执行结束后,该引用不再存在(即离开作用域);
    • 如果没有其他引用指向该对象,则下一次 GC 会将其回收。
    void method() {List<String> list = new ArrayList<>();list.add("Hello");
    }
    • 方法执行完后,list 变量消失;
    • 如果没有其他引用指向这个 ArrayList,GC 会回收它。

    4. 如何加快对象回收?(建议做法)

    • 将不再使用的对象设为 null(帮助 GC 更早识别无用对象);
    • 避免内存泄漏(如长生命周期对象持有短生命周期对象的引用);
    • 使用弱引用(WeakHashMap、SoftReference、PhantomReference)来辅助 GC 工作。

    总结

    项目内容
    最小执行单元线程(Thread)
    方法的作用逻辑封装单位,必须在线程中执行
    方法调用流程通过调用栈进行压栈、弹栈操作
    方法执行结束栈帧自动弹出,局部变量释放,堆中对象等待 GC
    垃圾回收机制自动管理堆内存,使用可达性分析算法
    内存释放时机对象不可达时,由 GC 在适当时间回收

    扩展

    垃圾回收的发展简要时间线:

    • 1958年    John McCarthy 在 Lisp 中实现第一个自动垃圾回收器
    • 1960年代~1970年代    多种函数式语言系统使用 GC 技术
    • 1983年    Smalltalk 使用 GC 管理对象内存
    • 1995年    Java 发布,GC 成为主流开发语言的重要组成部分
    • 2000年后    .NET、Python、Ruby、JavaScript、Go 等语言广泛采用 GC

    现在主流语言

    c/C++
    • 手工管理 malloc free/new delete
    • 忘记释放-memory leak-out of memory
    • 释放多次产生极其难易调试的bug,一个线程空间莫名其妙被另外一个释放了
    • 开发效率很低

    java python go js kotlin scala
    • 方便内存管理的语言

    • GC-GarbageCollector-应用线程只管分配,垃圾回收器负责回收

    • 大大减低程序员门槛

    rust
    • 运行效率超高(asmcc++)

    • 不用手工管理内存(没有GC)

    • 学习曲线巨高(ownership)

    • 你只要程序语法通过,基本就不会有bug


    http://www.hkcw.cn/article/YbYUVeHOkB.shtml

    相关文章

    单调栈的例题与代码

    首先&#xff0c;我们来看看例题&#xff1a; 给定一个长度为 N 的整数数列&#xff0c;输出每个数左边第一个比它小的数&#xff0c;如果不存在则输出 −1 。 输入格式&#xff1a; 第一行包含整数 N &#xff0c;表示数列长度。第二行包含 N 个整数&#xff0c;表示整数数列…

    事务Transaction

    事务&#xff08;Transaction&#xff09;是数据库管理系统中的一个重要概念&#xff0c;它是一组操作的集合&#xff0c;这些操作要么全部成功&#xff0c;要么全部失败&#xff0c;以确保数据的完整性和一致性。 一、事务的特性&#xff08;ACID&#xff09; 原子性&#xf…

    RPG改进1.轻击与重击的搭配与连续释放

    这一篇做不做都可以&#xff0c;后面视频作者会做的 就比如&#xff0c;当玩家想abaaba/aabaab/ababaa/abababab/aaaba/baabaa等搭配的释放时&#xff0c;可以进行改进。 1.创建动画通知 2.打开攻击的蒙太奇,添加动画通知 3.打开LightAttackMaster&#xff0c;添加变量 4.打开…

    MySQL 索引和事务

    目录 一&#xff1a;MySQL 索引介绍 1&#xff1a;索引概述 2&#xff1a;索引作用 3&#xff1a;索引的分类 &#xff08;1&#xff09;普通索引 &#xff08;2&#xff09;唯一索引 &#xff08;3&#xff09;主键索引 &#xff08;4&#xff09;组合索引&#xff08…

    MySQL 数据库操作

    目录 一. MySQL 数据库介绍 二. MySQL 库操作 1.系统数据库 2.数据库操作 三. MySQL 表操作 1.表介绍 2.查看表 3.创建表 4.查看表结构 5.修改表 6.复制和删除 四. MySQL 数据操作 1.插入数据 INSERT 2.删除与更新 INSERT 4.查询数据 INSERT 单表查询 1.单表…

    郑州首店停工?胖东来方面回应 工程正常对接中

    随着于东来此前公布的胖东来郑州首店开业日期(2026年元旦)临近,网友愈发关注该超市的动态。近日,有网友发现该店的建设似乎停工了。跟不久前热热闹闹的地面部分施工现场相比,如今很难见到工人师傅的身影,甚至“中建七局”几个大字已被拆除。这让网友们开始担忧是否能按计…

    女子穿高跟鞋跑步摔伤起诉健身房 责任划分引争议

    女子穿高跟鞋跑步摔伤起诉健身房 责任划分引争议!一名女子穿着高跟鞋在健身房跑步机上跑步,不久后因跟不上跑步机速度而摔倒,导致十级伤残。她随后起诉健身房要求赔偿。然而,健身房跑步机旁的墙上贴有不能穿高跟鞋跑步的提醒。2024年3月8日,刘娜(化名)穿着高跟鞋进入益阳…

    减肥走回家时家人会在路上迎接我

    减肥走回家时家人会在路上迎接我。责任编辑:zx0002

    沃尔沃高管谈汽车安全:不抢风头,只想多救一命

    沃尔沃高管谈汽车安全。4月15日晚,全新一代沃尔沃XC90正式上线,限时尊享价从47.9万元起跳。这台顶着“旗舰SUV”光环的北欧大块头,不但没来啥夸张参数堆料,也没整那些炫酷得让人眼花缭乱的智能化噱头——它依然稳稳地押注在“安全”两个字上,用最不招摇的方式稳扎传统豪华…

    主持人李彬因长期服药满头白发面部浮肿,却依旧保持乐观

    5月29日,知名主持人李彬罕见露面发视频,视频中李彬满头白发声音沙哑向大家问好。此前,李彬曾自曝生病,需长期服用药物导致面部浮肿,却依旧保持乐观。李彬,出生于河北省衡水市,中国影视演员、主持人,曾主持《超级大赢家》。责任编辑:zx0002

    .NET WinForm图像识别二维码/条形码并读取其中内容

    需求:图像识别出一张图片中的二维码或者条形码&#xff0c;并读取其中内容。 一、安装库(特别注意&#xff0c;网上很多都没说清楚) 如果是基于.net framework&#xff0c;则安装ZXing.Net(建议0.14.0版本左右&#xff0c;具体看实际&#xff0c;版本太高&#xff0c;部分接口…

    Java 注解与反射(超详细!!!)

    Java 注解与反射&#xff08;超详细&#xff01;&#xff01;&#xff01;&#xff09; 文章目录 Java 注解与反射&#xff08;超详细&#xff01;&#xff01;&#xff01;&#xff09;1.注解1.1内置注解1.1.1 SuppressWarnings注解用法 1.2 元注解1.3自定义注解 2.反射2.1 反…

    开关电源输出噪声--陶瓷 电解电容差异

    对于LED恒流源驱动&#xff0c;输出只用电解电容&#xff0c;噪声大 对于LED恒流源驱动&#xff0c;输出用电解电容和陶瓷电容&#xff08;C77& C78改成22uf陶瓷电容&#xff09;&#xff0c;噪声小到50 mV左右

    【运维实战】定时任务-crontab命令

    定时任务的应用场景 数据备份 定期对重要数据进行备份&#xff0c;是保障数据安全的重要手段。比如&#xff0c;我们可以设置每周日凌晨对整个数据库进行全量备份&#xff0c;或者每天对关键业务数据进行增量备份。这样&#xff0c;即便遇到硬件故障、误操作等意外情况&#…

    [免费]SpringBoot+Vue垃圾分类管理【论文+源码+SQL脚本】

    大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的SpringBootVue垃圾分类管理【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】SpringbootVue垃圾分类管理系统 Java毕业设计_哔哩哔哩_bilibili 项目介绍 本论文主要论述了如何使用JAVA语言…

    等保测评-Linux主机测评篇

    Linux主机测评 目录 Linux主机测评 0x01 前言 0x02 测评过程 1.身份的鉴别 a).对登陆的用户进行身份鉴别和标识&#xff0c;身份标识具有唯一性 b).应具有登录次数限制&#xff0c;登陆超时等措施 c).在进行远程控制中&#xff0c;防止传输过程被窃听 2.访问控制 a).…

    面向对象基本概念:多态;附带应用例子

    目录 一. 多态的概念简介 二. 多态的例子一&#xff1a;偏好过滤器 三. 多态的例子二&#xff1a;审查描述符(需要元编程知识) 四. 总结 面向对象编程(Object Oriented Programming&#xff0c;OOP)有三大核心概念&#xff1a;封装&#xff0c;继承&#xff0c;多态。前两个…

    Linux 串口连接乱码

    用到的全部软件&#xff0c;都放在这个网盘里面了&#xff0c;自取。 链接: https://pan.baidu.com/s/1AR6Lj8FS7bokMR5IrLmsIw?pwd3dzv 提取码: 3dzv 如果链接失效了&#xff0c;关注公号&#xff1a;每日早参&#xff0c;回复&#xff1a;资源&#xff0c;即可免费获取&…

    linux之web实战rsync

    一、rsync简介 rsync是用于数据备份共享以及增量同步的工具&#xff0c;它可以在本地计算机与远程计算机之间&#xff0c;或者两个本地目录之间同步文件&#xff08;但不支持两台远程计算机之间的同步&#xff09;。它也可以当作文件复制工具&#xff0c;替代cp和mv命令 二、…

    链表经典题目(力扣 easy)

    全部题目来自力扣&#xff0c;这里只做学习的记录&#xff0c;内容中部分为AI生成&#xff0c;有不对的地方可以评论或者私信哦~~ 203. 移除链表元素 &#xff08;版本一&#xff09;虚拟头节点法 # Definition for singly-linked list. # class ListNode: # def __init_…