static关键字的内存分析
通常情况下,Java把内存分为栈内存、堆内存和方法区
栈内存用来存放一些基本类型的变量和数组(数组也是一种引用类型)及对象的引用变量
堆内存主要是来放置对象的,即我们在程序中new出来的对象。
static,意味为静态的,用static修饰的变量和方法,实际上是给这些变量和方法指定了在内存中的”位置“(这个位置也叫静态区、方法区、数据区和共享区)。既然在内存中指定了位置,那么他们的 “大小”似乎就是固定的了,有了位置和大小的特征,在栈中或堆中开辟空间那就是非常的方便了。对于静态的东西,JVM在加载类时,就在內存中开辟了这些静态变量的空间(内存空间),即编译时就为这些成员变量的实例分配了空间。
下面我们来看一段代码
package demo; public class StaticDemo {
public static void main(String[] args) {
Visitor visitor1 = new Visitor();
System.out.println("count : " + visitor1.count);//
System.out.println("visitCount : " + Visitor.visitCount);// Visitor visitor2 = new Visitor();
System.out.println("count : " + visitor2.count);//
System.out.println("visitCount : " + Visitor.visitCount);// Visitor visitor3 = new Visitor();
visitor3.count = 5;
visitor3.visitCount = 0; // 归0
System.out.println("count : " + visitor1.count);//
System.out.println("count : " + visitor2.count);//
System.out.println("count : " + visitor3.count);//
System.out.println("visitCount : " + visitor1.visitCount);//
System.out.println("visitCount : " + visitor2.visitCount);//
System.out.println("visitCount : " + visitor3.visitCount);//
}
} class Visitor {
int count;
static int visitCount; public Visitor() {
count++;
visitCount++;
}
}
从上面代码来看,用static修饰的变量,每个类的实例改变的都是同一个副本,即在内存中static修饰的变量只有一份,而对于普通的成员变量,每个实例都有各自的副本,我们用图来简单的分析StaticDemo类的代码,首先JVM把Visit类与StaticDemo类编译完然后加载到方法区,在Visit方法区中,JVM检查到有个static修饰的变量visitCount,则又开辟了一块内存(叫做静态区)来存放,此时内存情况
接着JVM会自动寻找main方法并在栈中为其开辟一个空间,再看代码第5行
这时,来了一个访问者visitor1,JVM在栈中为visitor1开辟了一块内存,并且指向堆中的Visitor内存空间,由于count与visitCount为成员变量,所以有默认初始值0,根据代码
第6行与第7行的运行结果
我们可以得到count与visitCount变量在堆内存中的值
同理9,10,11行
与5,6,7行分析类似,此时内存情况及count与visitCount变量的值
接下来来了一个visitor3,把count与visitCount都重新赋值了
由于visitor1,visitor2,visitor3在堆空间中都有各自的count变量,所有当visitor3改变了count变量的值时,visitor1与visitor2的count变量值并没有受影响,而当visitor3对visitCount重新赋值了,因为visitor1,visitor2,visitor3的visitCount都为静态区中的0x0001,所以用visitor1,visitor2,visitor3访问的visitCount为最新的值0。可见,静态变量与具体的实例无关,属于整个类,在编程中,当所有对象共享某个数据的时候,我们就可以把这个成员变量定义为静态的,如上面的visitCount。
static关键字的内存分析的更多相关文章
- Java中this、static关键字的内存图解
Java中的关键字有很多,abstract default goto* null switch boolean do if package nchronzed break dou ...
- 面向对象编程(十)——继承之Super关键字及内存分析
Super关键字
- Java基础之static关键字的用法
Java中的static关键字主要用于内存管理.我们可以应用static关键字在变量.方法.块和嵌套类中. static关键字属于类,而不是类的实例. 静态(static)可以是: 变量 ...
- 你真的了解JAVA中对象和类、this、super和static关键字吗
作者:小牛呼噜噜 | https://xiaoniuhululu.com 计算机内功.JAVA底层.面试相关资料等更多精彩文章在公众号「小牛呼噜噜 」 目录 Java对象究竟是什么? 创建对象的过程 ...
- Java基础(二)-static关键字分析
static关键字是我们在编程中经常会使用到的,但有些可能只知其然而不知其所以然.下面介绍static关键字的作用再通过例子结合说明. static关键字共有五种作用(先说明static所修饰的不会改 ...
- static 关键字分析
在java中static 关键字用途很广,可以修饰成员变量 方法 甚至类(静态内部类),这里不分析static 修饰类 static修饰的内容的运行顺序 java的程序执行之前有一个类的加载的过程,在 ...
- 「C」关键字、标识符、注释、内存分析、数据、常量、变量
一.关键字 C语言提供的有特殊含义的符号,共32个. 一般在Xcode中关键字全部显示紫褐色,关键字全部都为小写.如int.return等. 二.标识符 标识符是程序员在程序中自定义的一些符号和名称. ...
- java执行程序的内存分析系列专栏二之static变量和方法内存分析
昨天写了简单的聊了下java执行程序时简单的内存划分,今天我们接着往下聊,聊聊static变量和方法的内存分析. 1.static变量和方法的第一个特性内存分析 statiic变量和方法的第一个特性能 ...
- java 内存分析之static
源码: 内存分析: 源码: 静态方法: 用static 声明的方法为静态方法,在调用该方法时,不会将对象的引用传递给它,所以在static 方法中不可访问非static 的成员. 可以通过对象 ...
随机推荐
- C#中的NameValueCollection简介
NameValueCollection继承自NameObjectCollectionBase,并且和一般的键值对不同的是,它支持集合中出现相同的Key. 引用:using System.Collect ...
- 解决使用ICsharpCode解压缩时候报错Size MisMatch4294967295;的错误
如果是一个文件夹生成的zip文件,解压缩时候不会报错. 如果是一个文件夹里面包含着两个子文件夹,而且每个子文件夹里面都有着文件.生成的zip文件在解压时候就出报这个错误. 具体的解决办法,通过网上搜索 ...
- 使用filter进行登录验证,并解决多次重定向问题
最近在做关于filter登录验证的功能,防止未登录的用户直接通过地址进入系统 LoginFilter类:继承Filter接口 package com.ss.filter; import java.io ...
- 程序媛计划——python初级课时1~2
在命令行中运行py文件:python 文件路径/文件名 python变量必须赋值后才能使用,因为py变量只有赋值后才会被创建. py可以同时给多个变量赋值:a,b,c = 10,20,'dfjkdj' ...
- C++一些函数的意义
1.重载 : C++ 允许多个函数拥有相同的名字,只要它们的参数列表不同就可以,这就是函数的重载 2.隐藏和覆盖的区别 IF 子类的函数与父类的名称相同,但是参数不同 父类函数被隐藏(还存在) ELS ...
- BZOJ 5334--[Tjoi2018]数学计算(线段树)
5334: [Tjoi2018]数学计算 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 220 Solved: 147[Submit][Status ...
- jzoj5879. 【NOIP2018提高组模拟9.22】电路图 B
tj:一道好題 看區間操作可以想到線段樹 並聯操作公式:a1∗a2/(a1+a2)a1*a2/(a1+a2)a1∗a2/(a1+a2) 串聯操作公式:a1+a2a1+a2a1+a2 我們發現,一個區間 ...
- Spring+Ehcache
这里记录一下Spring+Ehcache的结合使用 1.添加依赖 <dependency> <groupId>org.springframework</groupId&g ...
- javascript——后台传值map类型转换成json对象
前端需要对后端传过来的值进行解析之后再展示,而后端传过来的值可能是各种类型的,一般情况下要么和后端沟通下让他直接传给我们需要的类型,这个,我一般直接自己转,这次后端传回来一个map类型的对象,我转来转 ...
- JDK源码学习之 java.util.concurrent.automic包
一.概述 Java从JDK1.5开始提供了java.util.concurrent.atomic包,方便程序员在多线程环境下无锁的进行原子操作.原子变量的底层使用了处理器提供的原子指令,但是不同的CP ...