jvm 在执行程序的第一行字节码之前,会做怎样的准备工作?

228 天前
 gegeligegeligo

主要想问的是内存初始分配上的。
windows 上执行 exe ,装载器会解析该文件的头信息,确定程序的布局和代码段、数据段、堆栈段的大小,然后根据这些信息来分配合适的内存空间。
jvm 是怎么做的呢?
其它解释器,比如 cpython 、zend 、v8 是怎么做的呢?

1757 次点击
所在节点    Java
7 条回复
letianqiu
228 天前
jvm 本身也只是操作系统上的一个普通 process 。执行 bytecode 之前,jvm 需要先 bootstrap ,这个过程中会初始化一堆的标准库,main 函数所在的 class 也需要被 load 。另外就是 java thread 的 stack frame 是寄生在 native thread stack 上的
Rickkkkkkk
228 天前
有本书很好, 深入理解 jvm 虚拟机

你的问题都能回答, 包括 main 是怎么被执行起来的, 堆栈如何分配, 方法调用怎么跳转等等
letianqiu
228 天前
不建议看楼上提到的 深入理解 jvm 虚拟机,这本书的内容都是泛泛而谈,基本都是网上的内容拼凑出来的。尤其是关于 safe region 的部分,是直接翻译的 xiaofeng li 写的 blog 。如果想了解 jvm ,可以看封亚飞的揭秘 java 虚拟机和马智的深入剖析 Java 虚拟机入门。入门之后就只能看源码了
GeekGao
228 天前
主干过程:
1.Bootstrap:JVM 需要先进行 bootstrap 过程,这个过程中会初始化一堆的标准库,包括 Java 的核心类库;
2.加载主类:在 bootstrap 过程中,JVM 还需要加载包含 main 方法的类。这是因为 Java 程序的执行是从 main 方法开始的,所以 JVM 需要先找到并加载这个类;
3.初始化 Java 线程:Java 线程的栈帧是寄生在 native thread stack 上的,这意味着 JVM 需要在执行字节码之前,为 Java 线程准备好运行环境

抛开过程谈本质: 用数组、自定义 struct 、指针内存模拟 CPU 寄存器、内存。把 class 文件解析后加载到常量池、异常处理表等对应的结构中。然后调用 OS API ( ABI )开辟新的线程来模拟 CPU 工作。
GeekGao
228 天前
VM 的本质就是 C/C++指针和数据结构的 tricky skills 。内存分配和管理是非常大的知识范畴,几句话也说不明白
luozic
228 天前
额,完整的补起来: 可以先看
1.sicp 计算机程序的构造与结束

2. 再去编译一下 openjdk 的源码,推荐就用你现在主要用的 openjdk 8 or 17 21 ,去调试一下程序,打一下断点。 这里实际更推荐 实战 Java 虚拟机:JVM 故障诊断与性能优化(第 2 版) 葛一鸣的---这个是一步步非常详细的,不像深入 jvm 那本主要是介绍一个地图

3.垃圾回收算法手册-自动内存管理的艺术-英-理查德-琼斯

4. 再就是那些 算法优化案例,arthas jfr 1brc 挑战 ebpf 火焰图 逃逸分析等玩意了
这部分非常推荐看 openjdk 的部分 blog 还有工具。jitwatch 等。
luozic
228 天前
jvm 现在已经非常复杂了。
如果只是关注 openjdk---hotspot 系的,
可以看
1.JMM jdk 内存模型,

2. JVM special 文档, jvm specification https://docs.oracle.com/javase/specs/index.html
=======================================================
不过你确定你看得下去各个语言 language vm 的 specs 文档,即使是挑着和你问题相关的看,随便一个语言 VM 说清楚你这个问题也是百页英文,还得拉着代码断点调试 看看实现和 specs 的配套情况。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1033923

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX