由于最近时间充足,就看来一下sun关于JVM的文档,在对照了一下网上的相关文章,发现出入还真大哦,不知道是翻译的问题,还是个人理解问题,感觉怪怪的。
为了避免这种怪怪的感觉,个人觉得还是还是使用EN的比较好:
以下是官方文档资料地址:
http://java.sun.com/docs/books/jvms/second_edition/html/Overview.doc.html
根据官方文档的指导思想我们来看一片网上比较时髦的文章:
地址:http://www.webjx.com/exam/java-14986.html
请允许事先这样翻译这2个名词:
stack——栈
heap——堆
Java 把内存划分成两种:一种是栈内存,另一种是堆内存。在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配(这里需要解释一下,如果需要执行这个方法,会在stack上面创建一个frame,frame中保存在local variables和返回值),当在一段代码块定义一个变量时,Java 就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java 会自动释放掉为该变量分配的内存空间,该内存空间可以立即被另作它用。
堆内存用来存放由 new 创建的对象和数组,在堆中分配的内存,由 Java 虚拟机的自动垃圾回收器来管理。在堆中产生了一个数组或者对象之后,还可以在栈中定义一个特殊的变量,让栈中的这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或者对象,引用变量就相当于是为数组或者对象起的一个名称。引用变量是普通的变量,定义时在栈中分配,引用变量在程序运行到其作用域之外后被释放。而数组和对象本身在堆中分配,即使程序运行到使用 new 产生数组或者对象的语句所在的代码块之外,数组和对象本身占据的内存不会被释放,数组和对象在没有引用变量指向它的时候,才变为垃圾,不能在被使用,但仍然占据内存空间不放,在随后的一个不确定的时间被垃圾回收器收走(释放掉)(个人理解是stack中不再引用heap中对象的时候,这部分内存既会变成垃圾内存,需要回收)。
这也是 Java 比较占内存的原因,实际上,栈中的变量指向堆内存中的变量,这就是 Java 中的指针!
运行时数据区域(Runtime Data Areas)
JVM定义了一组运行时数据区域。这些区域再JVM运行程序时使用。一些区域在JVM启动的时候就被创建,在JVM关闭时销毁。还有些区域是每个线程所有的。线程启动时创建,线程结束时销毁。
pc 寄存器
JVM支持多线程。每个线程都有自己的pc(program counter)寄存器。任意时刻JVM线程执行某个方法的代码。如果方法不是native的,那么pc指向当前执行的JVM指令。如果是native 的,那么pc必须足够大来保存returnAddress或一个当前pingai平台下的本地指针。
JVM栈
每个线程都拥有一个私有的JVM stack,这个堆栈与线程一同创建。JVM栈和C语言的栈相似。由于JVM的Frame可以放在堆上,所以JVM stack可以是不连续的。JVM实现者应该让程序员可以控制初始栈的大小,并控制栈的最大最小值。JVM stack 可以动态增加。
Heap
JVM有一个堆,所有JVM中的线程共享这个堆。所有的类对象实例和数组都分配在堆上。
JVM堆在JVM启动的时候被创建。JVM提供一个垃圾收集者来管理堆。堆上的对象不需要程序员显式地销毁。堆可以是固定大小,也可以根据需要增加大小。堆可以是不连续的。
方法区域(Method Area)
JVM有一个方法区域,所有JVM中的线程共享这个区域。这个区域与C语言程序中的“text”段类似。在其中保存了每个类属的数据,比如 Runtime constant pool,field和method data,还有方法的字节码和构造函数,其中还包括类的“special methods”,还有实例和接口初始化代码。
Runtime constant pool
一个Runtime constant pool是代表了一个class文件中类或接口的常量表。其中包含若干常量,从编译期就固定的数值常量到编译期必须决定的方法和field的引用。Runtime constant pool类似与C语言中的符号表。
每个Runtime constant pool从JVM的Method Area 中分配。Runtime constant pool在类或接口被JVM创建的时候创建。
Native Method Stack
JVM可以使用传统的堆栈来支持本地方法。
Frame
Frame用来存储数据,部分返回结果,也用于动态连接,返回方法的结果,以及分发异常
每次调用方法,JVM都会再当前线程的Stack上创建一个Frame,当方法结束是销毁这个Frame。
每个Frame都有自己的局部变量数组,自己的操作数栈(operand stack)。
局部变量数组和操作数栈的大小在编译期就决定了。局部变量和操作数有当前Frame所属的方法提供。
Frame的大小由虚拟机的实现者决定。Frame所占用的内存可以在方法调用的时分配。
每个线程运行的某个时刻只能有一个Frame是活跃的,称为“当前Frame”。这个线程称为“当前线程”。包含这个方法的类称为“当前类”。当一个方法调用了另一个方法,那么它的Frame不在活跃,被调用的方法的Frame成为“当前Frame”。注意:两个线程创建的Frame是完全独立的。
局部变量
每个Frame都有一个局部变量数组,数组的长度取决于方法的局部变量个数。
单个局部变量可以存储:boolean, byte, char, short, int, float, reference和returenAddress
一对局部变量可以存储:long或double
局部变量用索引值来取址。第一个局部变量的索引是0。
JVM使用局部变量来传递方法参数。对于类方法,方法参数从局部变量“0”(零)开始。
对于实例方法,局部变量“0”被用来保存当前实例的引用值(this)。方法参数从局部变量“1”开始。
操作数栈(stack)
每个Frame都包含一个LIFO的栈,称为Operand Stack。该栈的最大深度在编译期决定,有创建Frame的方法代码决定。
JVM需要提供将局部变量或常量压入操作数栈的指令。其他指令可以操作栈上的数据,并将结果也压入栈。操作数栈也用于传递参数和接受返回值。
比如,iadd指令将两个int值加起来。这就需要被加的两个数在栈的最顶端。他们是由前面的指令压入栈的。两个数从栈中弹出。相加后的结果被压入栈。
动态连接(Dynamic Linking)
每个Frame包含一个指向当前 Runtime constant pool的引用,用来提供方法的动态链接。
方法代码是通过符号来引用变量和调用方法的。JVM动态的将符号翻译为具体的方法引用或变量的索引。
这就是Java实现晚绑定的机制。这种晚绑定使得代码变得更安全。
方法正常结束与异常结束
如果方法没有引起或抛出任何异常,那么方法会正常结束。需要指出的是,异常可以是由JVM直接抛出的,也可以是程序显式抛出的。
首先内存总体分为了4个部分,包括 stack segment、heap segment、code segment、data segment。
其中我们程序中用关键字new出来的东西都是存放在heap segment。
程序中的局部变量存放在stack segment,这些局部变量是在具体方法执行结束之后,系统自动释放内存资源(而heap segment中的资源需要java垃圾回收机制来处理)。
程序中的方法,是内存中的code segment中的,而且是多个对象 共享一个代码空间区域。
static静态变量,需要放在内存中的data segment中。
分享到:
相关推荐
### JVM学习笔记(一) #### 一、JVM概述与工具使用 JVM(Java Virtual Machine)是Java语言的核心组成部分之一,它为Java程序提供了一个跨平台的运行环境。本篇学习笔记主要介绍如何利用一系列工具来查看和监控JVM...
jvm学习路线图,可以供初步想学习的同学了解学习。。。
这个“java之jvm学习笔记五(实践写自己的类装载器)”很可能是对这一主题的详细探讨。 类装载器在Java中的主要职责是动态加载类到JVM中。Java的类装载器分为三个基本层次:启动类装载器(Bootstrap ClassLoader)、...
### JVM学习笔记 #### JVM内存模型 (JMM) JVM内存模型主要分为以下几个部分: - **Java堆**:这是所有线程共享的一块区域,在虚拟机启动时创建。主要用于存放对象实例,几乎所有的对象实例都在这里分配内存。 - *...
本篇JVM学习笔记主要涵盖了以下几个核心知识点: 1. **运行时数据区**: - **程序计数器**:记录当前线程执行的字节码的行号,用于线程恢复执行时跳转到正确位置。 - **Java虚拟机栈**:每个方法执行时创建的栈帧...
本文将深入探讨JVM中的访问控制器,主要基于“java之jvm学习笔记十一(访问控制器)-源码”这一主题,以及相关的源码分析。 首先,我们得了解Java的安全模型。Java安全模型基于一种称为安全管理器(SecurityManager)...
本资料集合包含了多个关于JVM学习的重要主题,旨在帮助读者从基础到深入地掌握JVM的工作原理和优化技巧。 1. **JVM运行机制** (2.JVM运行机制.pptx) JVM的运行机制包括类加载、字节码执行、内存管理等关键过程。类...
首先,JVM学习涉及多个层面,包括内存管理、类加载机制、垃圾收集、线程管理等。理解JVM内存模型至关重要,它主要分为堆内存(Heap)、方法区(Method Area)、栈内存(Stack)、本地方法栈(Native Method Stack)...
**JVM学习笔记(Java虚拟机)** Java虚拟机(JVM)是Java语言的核心组成部分,它是Java程序运行的平台,负责解释和执行字节码。深入理解JVM对于优化Java应用程序性能至关重要。本笔记将从以下几个方面详细介绍JVM:...
这个资料包不仅涵盖了理论知识,还包含个人的学习笔记,对于学习和掌握JVM的各个方面都将大有裨益。无论是初学者还是经验丰富的开发者,都可以从中找到提升自己技能的宝贵资源。通过深入学习和实践,可以更好地理解...
本篇JVM学习笔记主要关注对象声明、相关内存分配方法以及虚拟内存的物理和虚拟寻址概念。 首先,我们来看对象声明。在Java中,对象是在堆上创建的。例如,`CHeapObj` 类展示了如何在C++中模拟Java对象在堆上的分配...
NULL 博文链接:https://cooldatabase.iteye.com/blog/634599
### JVM学习笔记核心知识点整理 #### 一、引言与背景 随着软件开发技术的不断发展,Java作为一种广泛应用的编程语言,其背后的核心技术——Java虚拟机(JVM)的重要性日益凸显。掌握JVM不仅可以帮助开发者更好地理解...
JVM学习笔记(缓慢更新).md
《深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)周志明.pdf》这本书是Java开发者深入理解JVM(Java Virtual ...而“新建文本文档.txt”可能包含个人笔记或者临时记录,对于JVM学习的具体内容没有直接关系。
### JVM学习札记 #### 一、JVM运行机制 ##### 1、JVM的启动流程 JVM的启动过程主要包括以下步骤: 1. **加载配置文件**:JVM启动时,首先会根据当前路径寻找配置文件`JVM.CFG`,这个文件包含了JVM的一些基础设置...
本文将深入探讨JVM中的访问控制器,并通过分析"java之jvm学习笔记十一(访问控制器) -源码"中的`MySecurityManager`来进一步理解其工作原理。 访问控制器的主要任务是对类、方法和字段的访问进行限制,防止恶意代码...
是不是学习方向迷茫,老衲这有本葵花宝典之JVM学习路线,只要你按这个来学离高级工程师就进一步了,加油。