静态和动态内存分配 + 强类型和弱类型语言
编译时
编译时将代码转换为可执行形式的前一个阶段,。在java中,.java
文件在这个阶段被javac
编译器转换为.class文件。
javac fileName.java
通过上面的命令会生成一个名为fileName的.class文件,它将 java 代码转换为更接近本机机器语言的字节码。
运行
这是执行 .class 文件的第二阶段。在这里,JVM(Java 虚拟机)中的 java 编译器会将这个 .class 文件(字节码)转换为我们的处理器可以理解的机器码(10101…)。
可以通过以下命令执行此操作 -
java fileName // omit the .class
通过这样做,代码的输出结果将打印在终端的控制台窗口上。
现在,让我们谈谈静态内存分配。
静态内存分配
在编译期间分配的内存称为静态内存分配。分配的内存是固定的,或者说是在运行时不能更改。
public void getValue {
int [] array = {1,2,3,4,5}; // this is static memory allocation.
}
静态内存分配的缺点
大小是固定的,在运行时不能增加或减少。如果我们分配了一个巨大的大小并且没有完全使用它,我们最终将浪费内存,反之亦然,我们将耗尽内存,这称为堆栈溢出。因此,动态内存分配概念应运而生。
操作系统将内存分配给特定的应用程序或程序,下面是内存的体系结构。
堆
函数和局部变量存储在堆栈中。一小段堆栈内存分配给main()
方法,也称为堆栈帧,如下所示。
让我们举个例子来彻底理解这一点——
// function with local variables a,b and z
public class DynamicMemory {
public int getSum(int a, int b) {
int z = a + b;
return z;
}
public static void main(String[] args) {
DynamicMemory obj = new DynamicMemory();
int x = 10;
int y = 20;
int sum = obj.getSum(x, y);
System.out.println(“sum of 02 nos.= “ +sum);
}
}
该程序的执行步骤 -
main()
方法连同局部变量 x、y 和 z 将存储在堆栈帧内存区域的堆栈中。getSum()
函数及其局部变量 a 和 b 将存储在堆栈中。- 现在 main 函数暂停,直到
getSum()
函数执行并返回一个值。 - 一旦
getSum()
函数执行并返回一个值,它将从堆栈帧中删除,并且main()
方法将进入图片。 - 一旦
main()
也被执行,它将从堆栈中删除。现在堆栈是空的。
这个概念对于Recursion是必不可少的。
堆栈存储数据,直到函数执行。
堆
在运行时或执行时分配内存的过程称为动态内存分配。
堆是发生动态内存分配的内存段。与按上述定义的顺序分配和取消分配内存的堆栈不同,堆是随机发生分配和取消分配的内存段。
对象和实例变量存储在堆区。
DynamicMemory obj = new DynamicMemory(); // it will be stored in heap memory
新关键字
new
关键字在 java 程序中做了三件事 -
- 它将在堆区域中保留一个内存空间,并将所有非静态成员加载到该区域中。
- 它将这个内存区域的位置地址分配给对象。(在这种情况下是 obj)。
- 如果你没有为字段(变量)分配任何值,那么
new
将为这些变量分配默认值。
强类型语言和弱类型语言
让我们最后一次把它说出来——Java 是一种强类型和静态类型的语言。
另一方面,JavaScript 是一种弱类型和静态类型的语言。
强类型语言意味着一旦声明了具有特定数据类型的变量,就不能将其他类型的数据分配给该变量。编译器将抛出不匹配类型的编译时错误。
例如
int numA = 10;
byte numB = 1;
int numC = numB; // this will be done implicitly
byte numD = numA; // this will throw a compile-time error
byte numD = (byte) numA; // correct code
换句话说,当你将“较宽”数据分配给“较窄”数据类型变量时,编译器不会进行隐式类型转换。必须明确地进行窄类型转换。
- 点赞
- 收藏
- 关注作者
评论(0)