阅读前必须知道一点:
一个运行着的java程序并非一个进程,而是一个运行在虚拟机上的线程,这个线程里或许还运行着其他线程,运行着的虚拟机才是一个进程。
java每次运行至少要启动几个线程?
答案:两个,主线程(main)和垃圾收集线程。
主线程运行结束,其余线程跟着结束吗?
答案:不会的,主线程结束不会影响子线程的运行。
每当启动一个新线程的时候,java虚拟机都会为它分配一个java栈。java以栈帧为单位保存线程的运行状态。
虚拟机只会对java栈执行两种操作:以栈帧为单位的压栈或者出栈。
栈帧由三部分组成:局部变量区,操作数栈和帧数据区。 局部变量区和操作数栈要视对应的方法而定,它们是按照字长计算的。
局部变量区: java栈帧的局部变量区被组织为一个以字长为单位,从0开始计数的数组。字节码指令通过从0开始的索引来使用其中的数据。类型为int,float,reference和returnaddress的值在数组中只占一项,而类型为byte,short和char的值在存入数组前都将被转换为int(现在就明白为何InputStream的read()方法返回int)。但是long和double类型在数组中却占据连续的两项。
操作数栈和局部变量区一样。也被组织成一个以字长为单位的数组。但是不是通过索引来访问,而是通过标准栈操作--压栈和出栈来访问。
不同于程序计数器,java虚拟机没有寄存器,程序计数器也无法被程序指令直接访问。java虚拟机是由操作数栈而不是从寄存器中取得操作数的,因此它的运行方式是基于栈的而不是基于寄存器的。
虚拟机把操作数栈作为它的工作区--大多数指令都要从这里弹出数据,执行运算,然后把结果压回操作数栈。
若想更深入了解,请阅读下面:
以下摘自http://blog.csdn.net/yxysdcl/article/details/5569351
首先应该明白,栈是从高地址向低地址延伸的。每个函数的每次调用,都有它自己独立的一个栈帧,这个栈帧中维持着所需要的各种信息。寄存器ebp指向当前的栈帧的底部(高地址),寄存器esp指向当前的栈帧的顶部(地址地)。下图为典型的存取器安排,观察栈在其中的位置
入栈操作:push eax; 等价于 esp=esp-4,eax->[esp];如下图
出栈操作:pop eax; 等价于 [esp]->eax,esp=esp+4;如下图
我们来看下面这个C程序在执行过程中,栈的变化情况
void func(int m, int n) {
int a, b;
a = m;
b = n;
}
main() {
...
func(m, n);
L: 下一条语句
...
}
在main调用func函数前,栈的情况,也就是说main的栈帧:
从低地址esp到高地址ebp的这块区域,就是当前main函数的栈帧。当main中调用func时,写成汇编大致是:
push m
push n; 两个参数压入栈
call func; 调用func,将返回地址填入栈,并跳转到func
当跳转到了func,来看看func的汇编大致的样子:
__func:
push ebp; 这个很重要,因为现在到了一个新的函数,也就是说要有自己的栈帧了,那么,必须把上面的函数main的栈帧底部保存起 ; 来,栈顶是不用保存的,因为上一个栈帧的顶部讲会是func的栈帧底部。(两栈帧相邻的)
mov ebp, esp; 上一栈帧的顶部,就是这个栈帧的底部
;暂时先看现在的栈的情况
;到这里,新的栈帧开始了
sub esp, 8 ; int a, b 这里声明了两个int,所以esp减小8个字节来为a,b分配空间
mov dword ptr [esp+4], [ebp+12]; a=m
mov dword ptr [esp], [ebp+8]; b=n
这样,栈的情况变为:
ret 8 ; 返回,然后8是什么意思呢,就是参数占用的字节数,当返回后,esp-8,释放参数m,n的空间
由此可见,通过ebp,能够很容易定位到上面的参数。当从func函数返回时,首先esp移动到栈帧底部(即释放局部变量),然后把上一个函数的栈帧底部指针弹出到ebp,再弹出返回地址到cs:ip上,esp继续移动划过参数,这样,ebp,esp就回到了调用函数前的状态,即现在恢复了原来的main的栈帧。
相关推荐
### Java中堆内存与栈内存分配浅析 #### 一、引言 在Java编程语言中,内存管理是一项至关重要的技术。程序运行时所使用的内存主要分为两类:堆内存(Heap Memory)和栈内存(Stack Memory)。理解这两种内存类型的...
浅析java异常栈 Java 异常栈是Java编程语言中的一种机制,用于描述和处理程序中的错误和异常情况。在Java中,异常栈是指在Throwable对象抛出过程中所经历的多个方法调用层(方法调用栈)。越接近 throw 语句的方法...
浅析Java GUI编程工具集 本文主要介绍了Java GUI编程的三个主要工具集:AWT、Swing和SWT,并对其优缺点进行了比较。下面将对标题、描述、标签和部分内容进行详细的解释和分析。 标题: 浅析Java GUI编程工具集 ...
浅析JAVA代理模式.pdf
浅析Java语言的生存现状 本文概述 Java 语言的当前生存现状,从-java 语言的发展历程、应用系统、当前市场状况等方面进行分析。下面是相关知识点: Java 语言的发展历程 Java 语言的出现和发展得到了 IT 业界的...
每当进入一个方法,JVM会在栈上创建一个栈帧,存储方法的局部变量和操作数。当方法执行完毕,栈帧会被移除,相应的内存被释放。 3. **堆(Heap)**:堆是Java中动态分配内存的地方,用于存储new出来的对象。同一类...
浅析java常用的设计模式.doc
浅析 Java 学习中的“短板” Java 是一种流行的面向对象的编程语言,广泛应用于软件开发、Android 应用开发、Web 开发等领域。然而,在 Java 学习过程中,初学者容易出现一些“短板”,即一些被忽视或不了解的重要...
浅析Java的发展现状与趋势 Java是当今最流行的编程语言之一,自1995年由SUN公司发布以来,Java đã经历了多年的发展和演变。近年来,随着Oracle公司收购SUN公司,Java的发展方向和趋势备受关注。本文将对Java的...
"浅析Java企业开发" 本文将对Java企业开发的现状和发展趋势进行探讨,并对Struts、Hibernate、MyBatis和Spring这些开源框架进行分析。 首先, Java企业开发存在技术陈旧、保守,交付周期长,对新技术、新趋势的...
"浅析JAVA多线程在安卓应用程序中的应用" JAVA多线程技术在安卓应用程序中的应用是非常重要的,尤其是在需要执行耗时操作时,避免了主线程的阻塞,从而提高了用户体验。本文将浅析JAVA多线程在安卓应用程序中的应用...
浅析Java语言中的异常处理机制.pdf
### 浅析JAVA异常处理机制 #### 一、Java异常处理机制概述 异常处理是Java语言中的一个重要机制,它能够确保程序在遇到不可预料的情况时仍能维持稳定运行。异常处理主要包括三个方面:捕获异常、控制程序流程以及...
"浅析JAVA与C++的区别" Java和C++是两种最流行的程序设计语言,它们之间有很多的相似之处,但同时也存在很多的区别。下面我们将从技术角度对这两种语言的区别进行分析。 一、继承 C++支持类的多继承,而Java采用...
浅析Java卡应用执行机制及虚拟机能效优化 本文将对Java卡应用执行机制和虚拟机的能效优化进行深入分析。首先,我们将介绍Java卡应用执行机制的基本过程,然后讨论影响Java卡运算能效的因素,并探讨Java卡性能优化的...
"浅析java之对象数组" 本文主要探讨Java中对象数组的知识点,着重介绍基本数据类型数组和对象数组的声明、创建和使用。文章首先介绍了Java的基本概念和特点,然后详细探讨了一维数组的声明和使用,包括基本数据类型...
浅析JAVA语言的开发平台及J2EE编程技术.pdf
Java声音技术浅析 在Java世界里,多媒体技术的集成一直是开发者关注的焦点,其中声音技术尤为关键。本文将深入探讨Java对声音处理的支持,包括Applet中的声音播放、Java应用程序中的声音处理以及JavaX中Sound包的...
浅析JAVA编程中异常处理的方法与技巧.pdf