`
willvvv
  • 浏览: 329056 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

JVM中的堆和栈

阅读更多
JVM是基于堆栈的虚拟机.JVM为每个新创建的线程都分配一个堆栈.也就是说,对于一个Java程序来说,它的运行就是通过对堆栈的操作来完成的。堆栈以帧为单位保存线程的状态。JVM对堆栈只进行两种操作:以帧为单位的压栈和出栈操作。
我们知道,某个线程正在执行的方法称为此线程的当前方法.我们可能不知道,当前方法使用的帧称为当前帧。当线程激活一个Java方法,JVM就会在线程的 Java堆栈里新压入一个帧。这个帧自然成为了当前帧.在此方法执行期间,这个帧将用来保存参数,局部变量,中间计算过程和其他数据.这个帧在这里和编译 原理中的活动纪录的概念是差不多的.
从Java的这种分配机制来看,堆栈又可以这样理解:堆栈(Stack)是操作系统在建立某个进程时或者线程(在支持多线程的操作系统中是线程)为这个线程建立的存储区域,该区域具有先进后出的特性。
每一个Java应用都唯一对应一个JVM实例,每一个实例唯一对应一个堆。应用程序在运行中所创建的所有类实例或数组都放在这个堆中,并由应用所有的线程 共享.跟C/C++不同,Java中分配堆内存是自动初始化的。Java中所有对象的存储空间都是在堆中分配的,但是这个对象的引用却是在堆栈中分配,也 就是说在建立一个对象时从两个地方都分配内存,在堆中分配的内存实际建立这个对象,而在堆栈中分配的内存只是一个指向这个堆对象的指针(引用)而已。
Java为什么慢?JVM的存在当然是一个原因,但有人说,在Java中,除了简单类型(int,char等)的数据结构,其它都是在堆中分配内存(所以说Java的一切都是对象),这也是程序慢的原因之一。
我的想法是(应该说代表TIJ的观点),如果没有Garbage Collector(GC),上面的说法就是成立的.堆不象栈是连续的空间,没有办法指望堆本身的内存分配能够象堆栈一样拥有传送带般的速度,因为,谁会 为你整理庞大的堆空间,让你几乎没有延迟的从堆中获取新的空间呢?
这个时候,GC站出来解决问题.我们都知道GC用来清除内存垃圾,为堆腾出空间供程序使用,但GC同时也担负了另外一个重要的任务,就是要让Java中堆 的内存分配和其他语言中堆栈的内存分配一样快,因为速度的问题几乎是众口一词的对Java的诟病.要达到这样的目的,就必须使堆的分配也能够做到象传送带 一样,不用自己操心去找空闲空间.这样,GC除了负责清除Garbage外,还要负责整理堆中的对象,把它们转移到一个远离Garbage的纯净空间中无 间隔的排列起来,就象堆栈中一样紧凑,这样Heap Pointer就可以方便的指向传送带的起始位置,或者说一个未使用的空间,为下一个需要分配内存的对象"指引方向".因此可以这样说,垃圾收集影响了对 象的创建速度,听起来很怪,对不对?
那GC怎样在堆中找到所有存活的对象呢?前面说了,在建立一个对象时,在堆中分配实际建立这个对象的内存,而在堆栈中分配一个指向这个堆对象的指针(引 用),那么只要在堆栈(也有可能在静态存储区)找到这个引用,就可以跟踪到所有存活的对象.找到之后,GC将它们从一个堆的块中移到另外一个堆的块中,并 将它们一个挨一个的排列起来,就象我们上面说的那样,模拟出了一个栈的结构,但又不是先进后出的分配,而是可以任意分配的,在速度可以保证的情况下, Isnt it great?
但是,列宁同志说了,人的优点往往也是人的缺点,人的缺点往往也是人的优点(再晕~~).GC()的运行要占用一个线程,这本身就是一个降低程序运行性能 的缺陷,更何况这个线程还要在堆中把内存翻来覆去的折腾.不仅如此,如上面所说,堆中存活的对象被搬移了位置,那么所有对这些对象的引用都要重新赋值.这 些开销都会导致性能的降低.
此消彼长,GC()的优点带来的效益是否盖过了它的缺点导致的损失,我也没有太多的体会,Bruce Eckel 是Java的支持者,王婆卖瓜,话不能全信.个人总的感觉是,Java还是很慢,它的发展还需要时间.
分享到:
评论
1 楼 cectsky 2009-02-19  

相关推荐

    JVM中堆内存和栈内存的区别

    本文主要介绍了JVM中堆内存和栈内存的区别,具有很好的参考价值,下面跟着小编一起来看下吧

    堆和栈总结

    堆栈(stack),堆(heap) Java堆栈 jvm为每个新创建的线程都分配一个堆栈。堆栈以帧为单位保存线程的状态。jvm对堆栈只进行两种操作:以帧为单位的压栈和出栈操作。

    JVM 堆和栈的区别

    本文主要介绍了JVM堆和栈的区别。具有很好的参考价值,下面跟着小编一起来看下吧

    Java中堆和栈的区别详解

    主要介绍了Java中堆和栈的区别详解,所有的Java程序都运行在JVM虚拟机内部,我们这里介绍的自然是JVM(虚拟)内存中的堆和栈,需要的朋友可以参考下

    JVM堆栈性能分析

    Thread Dump 是非常有用 Java应用问题的工具。每一个 Java 虚拟机 都有及时生成所有线程在某...照,及JVM 中所有 Java线程的堆栈跟踪信息,堆栈信息一般包含完整的类名 及所执行的方法,如果可能的话还有源代码的行数。

    深入JVM内核 - 原理、诊断与优化

    熟悉和掌握JVM平台有着重要的实用价值和意义。 在本课程中个,将详细介绍JVM的基本原理、组成以及工作方式,并配合实际案例,介绍相关的调优技巧。 课程大纲: 第一课 初识JVM JVM分类 Java语言规范 JVM规范 ...

    深入JVM内核—原理、诊断与优化

    第二周JVM运行机制简介堆、栈、方法区等JVM启动流程内存模型和volatile实例解释和编译运行的概念介绍JVM的内部结构、启动流程以及内存模型。并介绍JVM字节码的执行方式。第三周常用JVM参数堆的分配参数栈分 资源太大...

    Java中栈内存和堆内存详解

    Java中栈内存和堆内存详解,非常容易理解

    JVM规范--高手总结

    2.5.4 堆(heap)和栈(stack) 20 JAVA垃圾收集器 21 3.1 垃圾收集简史 21 3.2 常见的垃圾收集策略 21 3.2.1 Reference Counting(引用计数) 22 3.2.2 跟踪收集器 22 3.3 JVM的垃圾收集策略 27 3.3.1 Serial Collector ...

    JVM内存管理和JVM垃圾回收

    你对JVM内存组成结构和JVM垃圾回收机制是否熟悉,这里和大家简单分享一下,希望对你的学习有所帮助,首先来看一下JVM内存结构,它是由堆、栈、本地方法栈、方法区等部分组成,结构图如下所示。

    简单实用JVM参数配置

    Java虚拟机包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域。 JVM屏蔽了与具体操作系统平台相关的信息,使Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上...

    葛一鸣,深入JVM内核—原理、诊断与优化

    课程大纲: 第一课 初识JVM JVM分类 Java语言规范 JVM规范 介绍JVM的基本知识和发展历史,并介绍了Java语言规范和JVM规范。...堆、栈、方法区等 JVM启动流程 内存模型和volatile实例 解释和编译运行的概念

    JVM实战高手.zip

    程序计数器、虚拟机栈、本地方法栈 3 个区域随线程生灭(因为是线程私有),栈中的栈帧随着方法的进入和退出而有条不紊地执行着出栈和入栈操作。而 Java 堆和方法区则不一样,一个接口中的多个实现类需要的内存可能不...

    Java中堆内存和栈内存详解

    我开始饿时候一直对java的堆栈之间的关系有点模糊,虽然能说出来他之间的区别,但是并...后来仔细研究了下这个问题,还单独米勒jvm的书看,自己也有了些许深入的掌握,我在这里面用了些例子说明,可能大家会容易接受!

    java虚拟机JVM详解ppt

    详细介绍了java虚拟机和java内存区域的描述解释,并针对堆和栈的内存溢出进行了案例描述,是不可多得的分享资料

    Java栈内存与堆内存

    在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间...

    Java进阶教程解密JVM视频教程

    4. 堆 5. 方法区 6. 直接内存 第三章:垃圾回收 1. 如何判断对象可以回收 2. 垃圾回收算法 3. 分代垃圾回收 4. 垃圾回收器 5. 垃圾回收调优 第四章:类加载与字节码技术 1. 类文件结构 2. 字节码指令 3. 编译期...

    最新java面试专题01-JVM

    JVM内存结构:JVM的内存结构主要包括堆内存、方法区、栈(包括Java虚拟机栈和本地方法栈)、程序计数器等。堆内存是所有线程共享的内存区域,用于存放对象实例;方法区保存已加载的类信息、常量、静态变量和编译后的...

    论文研究-基于JVM内存模型的String分析 .pdf

    基于JVM内存模型的String分析,王培,程明,本文首先介绍了运行时的Java程序的内存管理模型中的方法区、堆和Java栈等几块内存区域,又介绍了存于堆中的常量池这块比较特殊的内�

Global site tag (gtag.js) - Google Analytics