了解Java中静态方法和静态变量的存储
在每种编程语言中,内存都是至关重要的资源,而且在本质上也是稀缺资源。因此,必须彻底管理内存而没有任何泄漏。内存的分配和释放是一项关键任务,需要非常小心和考虑。在本文中,我们将了解Java中静态方法和静态变量的存储。 Java虚拟机 (JVM) 是一个提供运行时环境来驱动Java代码的引擎。它将Java字节码转换成机器语言。 JVM 有两个主要功能。他们是:
- 它允许Java程序在任何设备或操作系统上运行,以实现 WORA(Write Once Run Anywhere)原则。
- 它管理和优化程序内存。
JVM 内存管理器在程序运行期间创建内存池。让我们了解一下Java中内存池的概念。有两种类型的内存池,即栈内存和堆内存。堆栈内存和堆内存之间的主要区别在于堆栈仅用于存储小数据类型,而堆存储类的所有实例。而且,由于Java隐式或显式地从 Object.class 扩展类,我们创建的每个类都是对象的集合。这也意味着我们不能使用方法或变量,除非我们用 new 关键字实例化它。一旦我们实例化方法,JVM 就会在堆上分配一些内存,并将实例的地址存储在堆栈上。在此之后,可以使用方法和变量。为了更好地理解新关键字的工作原理,我们举个例子。让我们参加鸟类课程。每当发现一只新鸟时,就需要增加鸟的数量。让我们尝试实现这段代码:
Java
// Java program to demonstrate the above example
public class Bird {
private String name;
private int number;
Bird(String name)
{
this.name = name;
number++;
}
public void fly()
{
System.out.println(
"This bird flies");
}
public int getNumber()
{
return number;
}
public String getName()
{
return name;
}
}
class GFG {
public static void main(String args[])
{
Bird b1 = new Bird("Parrot");
Bird b2 = new Bird("Sparrow");
Bird b3 = new Bird("Pigeon");
System.out.println(b1.getNumber());
}
}
Java
// Java program to demonstrate the above example
public class Bird {
private String name;
private static int number;
Bird(String name)
{
this.name = name;
number++;
}
public void fly()
{
System.out.println("This bird flies");
}
public int getNumber()
{
return number;
}
public String getName()
{
return name;
}
}
class GFG {
public static void main(String args[])
{
Bird b1 = new Bird("Parrot");
Bird b2 = new Bird("Sparrow");
Bird b3 = new Bird("Pigeon");
System.out.println(b1.getNumber());
}
}
1
显然,这种方法不能用于计算鸟类的数量,因为在每个实例中,都分配了一个新堆,并且对于所有实例,鸟类的数量从 0 开始初始化并递增到 1。因此,我们正在创建三个独立的鸟,在每个鸟对象中,鸟的数量为 1。为了避免这种情况,我们将方法和变量初始化为static 。这意味着变量或方法不会为每个新对象的创建而改变。由于这些方法和变量不能存储在普通堆中,因此它们存储在称为永久代(PermGen)的特殊区域中。
The main difference is that the heap is the auto growing space, with RAM memory as its constraints, whereas this PermGen has a fixed space allocation, and this is shared with all the instances.
让我们通过将数字更改为静态变量来实现这一点。
Java
// Java program to demonstrate the above example
public class Bird {
private String name;
private static int number;
Bird(String name)
{
this.name = name;
number++;
}
public void fly()
{
System.out.println("This bird flies");
}
public int getNumber()
{
return number;
}
public String getName()
{
return name;
}
}
class GFG {
public static void main(String args[])
{
Bird b1 = new Bird("Parrot");
Bird b2 = new Bird("Sparrow");
Bird b3 = new Bird("Pigeon");
System.out.println(b1.getNumber());
}
}
3
注意:在Java 5 和 6 中,使用了 PermGen 空间。但是由于Java 8 中内存模型的重大变化,存储规范也发生了变化。现在引入了一个新的内存空间“ MetaSpace ”,其中存储了类的所有名称字段、带有方法字节码的类的方法、常量池、JIT 优化。 Java 8.0 中 PermGen 发生这种变化的主要原因是很难预测 PermGen 的大小,它有助于提高垃圾回收性能。