1、heap和stack的区别
什么时候使用heap和stack不取决于变量类型,而是取决于要变量的生存空间(内存生存期??)。例如:全局变量定义在heap中,动态局部变量定义在stack中。Heap的使用代价要比stack高,而且要慢。
Heap速度慢的原因有:
分配操作:特别是空闲列表没有块时;
释放操作:释放内存时的收集操作;
堆竞争:多线程时;
总之,heap速度慢是因为频繁的分配和重分配。
stack的空间大小有限定,vc的缺省是2M。栈不够用的情况一般是程序中分配了大量数组和递归函数层次太深。有一点必须知道,当一个函数调用完返回后它会释放该函数中所有的栈空间。栈是由编译器自动管理的,不用用户操心。
heap是动态分配内存的,并且你可以分配使用很大的内存。但是用不好会产生内存泄漏。并且频繁地malloc和free会产生内存碎片(有点类似磁盘碎片),因为c分配动态内存时是寻找匹配的内存的。而用栈则不会产生碎片。
heap:堆,在程序中,使用堆来动态的分配和释放对象,也就是用户new出来的内存,必须用delete释放。当new了对象但没有释放时,就会造成内存泄漏。Java的垃圾回收机解决了这个问题,它会帮你释放这部分内存。
下列情况下调用堆操作:事先不知道程序所需对象的数量和大小;对象太大而不适合堆栈分配程序。另外,全局变量、静态变量都是创建在heap上的。注:java这中,没有全局变量,只有静态变量。
stack:栈,其上内容是编系统分配给进程的,只要进程结束就会自动回收。函数体内定义的变量会保存在stack中。因此在GC(没有指针的语言)中,全部分配在heap中,就没有stack这样的说法了。栈是先入后出的,一般是由高地址向低地址生长。
例1:
int a = 0; 全局初始化区
char *p1; 全局未初始化区
main()
{
int b; 栈
char s[] = “abc”;栈
char *p2; 栈
char *p3 = “123456″; 123456在常量区,p3在栈上。
static int c =0; 全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
分配得来得10和20字节的区域就在堆区。
strcpy(p1, “123456″); 123456放在常量区,编译器可能会将它与p3所指向的”123456″优化成一块。
}
例2:
char s1[] = “aaaaaaaaaaaaaaa”;
char *s2 = “bbbbbbbbbbbbbbbbb”;
aaaaaaaaaaa是在运行时刻符值的,而bbbbbbbbbbb是在编译时就确定的
但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。
在C++中,指针长度为四字节,并且都是变量或者参数形式存在的,所以都存贮
在栈中;而指针所指向的对象是new在堆中的。
2、java中的static
从某种程度上可以说java中的static函数和变量类似于C语言中的全局函数和全局变量。
1、static变量
整个程序中,只有一份,即只分配一块存储空间,而且所有此类的方法都可以操作修改该空间。Static变量或者static程序段在第一次装载时就进行初始化,涉及继承时,先初始化父类的static变量,然后是子类的static变量。
2、static方法
不需要创建对象就可使用,因此静态方法常用来为应用程序提供一些使用的方法。静态方法的调用方式为“类名.方法名”。
3、static类
通常一个普通类不允许声明为静态的,只有一个内部类才可以。这时这个声明为static的内部类可以直接作为一个普通类来使用,而不需实例一个外部类。
3、变量的初始化顺序
装载时初始化static变量及static程序段内的变量:先父类,后子类;
装载完毕,初始化main()内的变量―>创建对象,先初始化此类的变量,再调用构造函数:先父类构造函数,再子类构造函数。
This entry was posted on Thursday, July 20th, 2006 at 6:15 pm
分享到:
相关推荐
以下是对Java程序初始化顺序的详细说明: 1. **类加载阶段**: - **加载**:当Java虚拟机(JVM)首次遇到一个类的引用时,会通过类加载器进行加载。加载过程包括找到类的.class文件,读取其字节码,并转化为内存中...
这个"java代码的初始化顺序demo"显然旨在演示这一过程。让我们深入探讨Java中的初始化顺序及其背后的机制。 1. **类加载阶段**: 在Java程序运行时,JVM会先加载类的字节码文件(.class文件)。这个过程包括加载、...
在实际开发中,理解这个初始化顺序是非常重要的,尤其是在设计复杂的类结构或者涉及单例模式、线程安全初始化等场景时。如果在构造器或初始化块中依赖其他静态或非静态成员,必须确保这些成员在需要之前已经被正确...
总之,深入理解Java的ClassLoader机制和类变量初始化顺序是提升Java编程技能的重要步骤。通过学习这些知识点,开发者可以更好地优化代码、设计更健壮的系统,并解决与类加载和初始化相关的复杂问题。
总之,类的初始化顺序是:静态成员 -> 静态初始化块 -> 非静态成员 -> 非静态初始化块 -> 构造器。这个顺序同样适用于继承关系,只是会先初始化父类的部分,再初始化子类的部分。掌握这一知识能帮助程序员更好地设计...
本文将深入探讨Java中的初始化过程,包括对象的构造器初始化以及类成员的初始化顺序,同时也会涉及Java的垃圾回收机制,即内存的自动清理。 首先,让我们详细了解一下Java中的构造器初始化。构造器是Java中用于初始...
Java对象的初始化顺序是一个关键的编程概念,它涉及到类加载、静态初始化、实例初始化等多个步骤。下面我们将详细探讨这些步骤。 首先,当程序运行并创建一个新的对象时,JVM(Java虚拟机)会按照特定的顺序来初始...
Java初始化和清理是Java语言中非常重要的两个过程,它们确保了Java程序的正确运行和资源的有效管理。Java的初始化包括类的加载、连接和初始化三个过程,而清理则主要指垃圾回收机制。 首先,Java初始化的主要特性...
Java内存模型,简称JMM(Java Memory Model),是Java编程语言规范的一部分,它定义了程序中各个线程如何访问和修改共享变量,以及如何确保数据的一致性。深入理解Java内存模型对于编写高效的并发程序至关重要。本文...
静态变量的初始化顺序按照它们在源代码中的出现顺序进行,而静态块则是在类加载时按顺序执行的。例如,在`JvmTest.java`和`JvmTest1.java`中,如果有静态变量和静态初始化块,它们的执行顺序将体现在`<clinit>`方法...
Java虚拟机(JVM)是Java程序运行的核心,它的内部机制包括了类的加载、链接、初始化等关键过程。在Java编程中,了解这些过程对于优化程序性能、理解和解决类加载问题至关重要。本文将深入探讨Java虚拟机中的类初始...
这个结果与我们的直觉相悖,其背后的原因在于JVM的初始化顺序。 当类被加载时,JVM会按照如下顺序执行: 1. **类加载**:将类加载到内存中。 2. **连接**:包括验证、准备和解析阶段。 3. **初始化**:在这个阶段...
Java虚拟机JVM类加载初始化是Java程序运行过程中的关键环节,它负责将类的字节码文件加载到内存中并进行相应的处理,以便程序能够正确执行。在Java中,类加载器(Classloader)扮演着核心角色。下面将详细讨论类加载...
- **final域的初始化安全性**:对于一个final变量,一旦初始化完成,其他线程就能看到初始化后的值。 深入理解Java内存模型可以帮助开发者避免并发编程中常见的问题,如数据竞争、死锁和活锁等。通过合理地使用同步...
### Java内存对象分配过程研究 #### 一、引言 Java作为一门强大的面向对象编程语言,在实际开发过程中,对象的创建及其内存管理是至关重要的环节。深入理解对象在内存中的分配过程不仅能够帮助开发者设计出更为...
本文将深入探讨Java变量的声明、内存分配以及初始化。 首先,变量的声明是指在程序中定义一个变量,指定其类型和名称。例如,`String name;` 和 `int age;` 在`Person`类中声明了两个变量,`name`是一个字符串类型...
数组初始化时,Java会为数组的所有元素分配内存,并根据初始化列表为每个元素赋予初始值。对于未初始化的数组,如`int[] b = new int[5];`,虽然在堆上分配了足够的空间,但元素的初始值默认为该类型的默认值(如int...
比如,我们可以通过合理地安排初始化顺序,优化代码结构,避免不必要的资源消耗。此外,对于一些复杂的并发场景,理解初始化过程可以帮助我们预防潜在的线程安全问题。 总的来说,Java字节码的深入研究能够使开发者...
1. **内存层次结构**:Java 内存模型将内存分为堆内存、栈内存、方法区(在 Java 8 及以后版本中被元空间替代)和程序计数器等几个区域,其中堆存储对象实例,栈存储局部变量,方法区存储类信息,程序计数器则用于...