通常情况下,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关键字的内存分析的更多相关文章

  1. Java中this、static关键字的内存图解

    Java中的关键字有很多,abstract  default  goto*  null  switch  boolean  do  if  package  nchronzed  break  dou ...

  2. 面向对象编程(十)——继承之Super关键字及内存分析

    Super关键字

  3. Java基础之static关键字的用法

    Java中的static关键字主要用于内存管理.我们可以应用static关键字在变量.方法.块和嵌套类中. static关键字属于类,而不是类的实例.        静态(static)可以是: 变量 ...

  4. 你真的了解JAVA中对象和类、this、super和static关键字吗

    作者:小牛呼噜噜 | https://xiaoniuhululu.com 计算机内功.JAVA底层.面试相关资料等更多精彩文章在公众号「小牛呼噜噜 」 目录 Java对象究竟是什么? 创建对象的过程 ...

  5. Java基础(二)-static关键字分析

    static关键字是我们在编程中经常会使用到的,但有些可能只知其然而不知其所以然.下面介绍static关键字的作用再通过例子结合说明. static关键字共有五种作用(先说明static所修饰的不会改 ...

  6. static 关键字分析

    在java中static 关键字用途很广,可以修饰成员变量 方法 甚至类(静态内部类),这里不分析static 修饰类 static修饰的内容的运行顺序 java的程序执行之前有一个类的加载的过程,在 ...

  7. 「C」关键字、标识符、注释、内存分析、数据、常量、变量

    一.关键字 C语言提供的有特殊含义的符号,共32个. 一般在Xcode中关键字全部显示紫褐色,关键字全部都为小写.如int.return等. 二.标识符 标识符是程序员在程序中自定义的一些符号和名称. ...

  8. java执行程序的内存分析系列专栏二之static变量和方法内存分析

    昨天写了简单的聊了下java执行程序时简单的内存划分,今天我们接着往下聊,聊聊static变量和方法的内存分析. 1.static变量和方法的第一个特性内存分析 statiic变量和方法的第一个特性能 ...

  9. java 内存分析之static

    源码: 内存分析: 源码: 静态方法:   用static 声明的方法为静态方法,在调用该方法时,不会将对象的引用传递给它,所以在static 方法中不可访问非static 的成员.   可以通过对象 ...

随机推荐

  1. 基于JMS的ActiveMQ搭建与实现

    1.JMS Java消息服务(Java Message Service)即JMS,是一个Java平台中关于面向消息中间件的API,用于两个程序之间,或分布式系统中发送消息,进行异步通信. JMS包括队 ...

  2. 20164317《网络对抗技术》Exp4 恶意代码分析

    1.实践目标 1.是监控你自己系统的运行状态,看有没有可疑的程序在运行. 2.是分析一个恶意软件,就分析Exp2或Exp3中生成后门软件:分析工具尽量使用原生指令或sysinternals,systr ...

  3. 20164317《网络对抗技术》Exp1 PC平台逆向破解

    实验目的: 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串. 该程序同时包含另一个代码片段,getSh ...

  4. JAVA 定时器时间格式

    格式: [秒] [分] [小时] [日] [月] [周] [年] 通配符说明: \*:表示所有值.例如:在分的字段上设置"\*",表示每一分钟都会触发. ?:表示不指定值.使用的场 ...

  5. 盘点Xcode中开发者最喜爱的十大开源插件

    Xcode IDE拥有着诸如导航.重构.校准等众多非常高大上的工具,而予以辅助的插件更是在Xcode的基础上对相关功能进行改进与扩展.在应用开发过程中,通过开源包管理器Alcatraz对插件进行安装管 ...

  6. .NET Windows Form 改变窗体类名(Class Name)有多难?

    研究WinForm的东西,是我的一个个人兴趣和爱好,以前做的项目,多与WinForm相关,然而这几年,项目都与WinForm没什么关系了,都转为ASP.NET MVC与WPF了.关于今天讨论的这个问题 ...

  7. Dockerfile指令详解上

    COPY复制文件指令 和RUN命令一样,COPY命令也有两种格式,一种类似与命令行,一种类似与函数调用,命令格式如下: COPY ... COPY ["",...] COPY将构建 ...

  8. 使用 find 命令实现高级排除需求

    使用 find 命令实现高级排除需求 Linked 关于 find 命令,本博客介绍过 atime,ctime,mtime 介绍过 --exec 参数. 介绍这些的基本需求是进行文件管理.事实上,基于 ...

  9. (原创)JAVA阻塞队列LinkedBlockingQueue 以及非阻塞队列ConcurrentLinkedQueue 的区别

    阻塞队列:线程安全 按 FIFO(先进先出)排序元素.队列的头部 是在队列中时间最长的元素.队列的尾部 是在队列中时间最短的元素.新元素插入到队列的尾部,并且队列检索操作会获得位于队列头部的元素.链接 ...

  10. express+nodemon 修改后浏览器自动刷新

    添加nodemon模块 cnpm install --save nodemon 根目录添加文件 nodemon.json { "restartable": "rs&quo ...