Java基础-方法区以及static的内存分配图
转载自: https://blog.csdn.net/Wang_1997/article/details/52267688
前面的几篇都没有太明确地指出 方法区 是什么?现在通过一些资料的收集和学习,下面做一些总结
什么是方法区:
方法区是系统分配的一个内存逻辑区域,是JVM在装载类文件时,用于存储类型信息的(类的描述信息)。
方法区存放的信息包括:
类的基本信息:
1.每个类的全限定名
2.每个类的直接超类的全限定名(可约束类型转换)
3.该类是类还是接口
4.该类型的访问修饰符
5.直接超接口的全限定名的有序列表
已装载类的详细信息
1. 运行时常量池:在方法区中,每个类型都对应一个常量池,存放该类型所用到的所有常量,常量池中存储了诸如文字字符串、final变量值、类名和方法名常量。
2. 字段信息:字段信息存放类中声明的每一个字段的信息,包括字段的名、类型、修饰符。
3. 方法信息:类中声明的每一个方法的信息,包括方法名、返回值类型、参数类型、修饰符、异常、方法的字节码。
(在编译的时候,就已经将方法的局部变量、操作数栈大小等确定并存放在字节码中,在装载的时候,随着类一起装入方法区。)
4. 静态变量:类变量,类的所有实例都共享,我们只需知道,在方法区有个静态区,静态区专门存放静态变量和静态块。
5. 到类classloader的引用:到该类的类装载器的引用。
6. 到类class 的引用:虚拟机为每一个被装载的类型创建一个class实例,用来代表这个被装载的类。
下面分析static的内存分配
public class Dome_Static {
public static void main(String[] args) {
Person p1 = new Person();
p1.name = "xiaoming";
p1.country = "chinese";
Person p2 = new Person();
p2.name = "xiaohong";
p1.speak();
p2.speak();
}
}
class Person {
String name;
static String country;
public void speak() {
System.out.println("name:"+name+",country:"+country);
}
}
- Output:
- name:xiaoming,country:chinese
- name:xiaohong,country:chinese
1.首先,先加载Dome_Static,然后其main函数入栈,之后Person被加载。static声明的变量会随着类的加载而加载,所以在内存中只会存在一份,实例化多个对象,都共享同一个static变量,会默认初始化
2.在栈内存为 p1 变量申请一个空间,在堆内存为Person对象申请空间,初始化完毕后将其地址值返回给p1,通过p1.name和p1.country修改其值
3.在栈内存为 p2 变量申请一个空间,在堆内存为Person对象申请空间,初始化完毕后将其地址值返回给p2,仅仅通过p2.name修改其值
4.打印show方法,进栈,这里就不画图了,对于栈相关的概念不清楚的可以看看在之前发的博客。简单口述下:p1.show() show方法入栈,在方法的内部有个指向堆内存的this引用,通过该引用可找到堆内存实体,打印country时,可通过该堆内存对象找到对应的类,读取对应静态区中的字段值
最后给大家一道面试题练练手,要求写出其结果(笔试)
public class StaticTest {
public static int k = 0;
public static StaticTest t1 = new StaticTest("t1");
public static StaticTest t2 = new StaticTest("t2");
public static int i = print("i");
public static int n = 99;
public int j = print("j");
{
print("构造块");
}
static{
print("静态块");
}
public StaticTest(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++n;
++i;
}
public static int print(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++i;
return ++n;
}
public static void main(String[] args) {
StaticTest t = new StaticTest("init");
}
}
结果:
1:j i=0 n=0
2:构造块 i=1 n=1
3:t1 i=2 n=2
4:j i=3 n=3
5:构造块 i=4 n=4
6:t2 i=5 n=5
7:i i=6 n=6
8:静态块 i=7 n=99
9:j i=8 n=100
10:构造块 i=9 n=101
11:init i=10 n=102
这个留给大家去思考,如果一眼便能便知道为什么是这样的输出结果,那么静态方面知识应该比较扎实了
提示一下 :
1.加载的顺序:先父类的static成员变量 -> 子类的static成员变量 -> 父类的成员变量 -> 父类构造 -> 子类成员变量 -> 子类构造
2.static只会加载一次,所以通俗点讲第一次new的时候,所有的static都先会被全部载入(以后再有new都会忽略),进行默认初始化。在从上往下进行显示初始化。这里静态代码块和静态成员变量没有先后之分,谁在上,谁就先初始化
3.构造代码块是什么?把所有构造方法中相同的内容抽取出来,定义到构造代码块中,将来在调用构造方法的时候,会去自动调用构造代码块。构造代码快优先于构造方法。
Java基础-方法区以及static的内存分配图的更多相关文章
- Jvm方法区以及static的内存分配图
前面的几篇都没有太明确地指出 方法区 是什么?现在通过一些资料的收集和学习,下面做一些总结 什么是方法区: 方法区是系统分配的一个内存逻辑区域,是JVM在装载类文件时,用于存储类型信息的(类的描述信息 ...
- Java基础-方法(method)的应用
Java基础-方法(method)的应用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 方法就是定义在类中,具有特定功能的一段小程序,方法也称为函数(function),方法可以接 ...
- Java基础——方法的调用
Java基础--方法的调用 总结: 1. 在同一个类中-- 对于静态方法,其他的静态和非静态方法都可以直接通过"方法名"或者"类名.方法名"调用它. 对 ...
- 《Java基础——方法的调用》
Java基础--方法的调用 总结: 1. 在同一个类中-- 对于静态方法,其它的静态和非静态方法都可以直接通过"方法名"或者"类名.方法名"调用它. 对 ...
- JAVA基础-栈与堆,static、final修饰符、内部类和Java内存分配
Java栈与堆 堆:顺序随意 栈:后进先出(Last-in/First-Out). Java的堆是一个运行时数据区,类的对象从中分配空间.这些对象通过new.newarray.anewarray和mu ...
- 夯实Java基础(七)——Static关键字
1.static介绍 static关键字一直是各大企业中面试常常会问到的问题,主要考察面试者的基础是否扎实,下面来介绍一下static关键字. Java中static表示“全局”或者“静态”的意思,可 ...
- 黑马程序员——JAVA基础之函数,重载,内存结构
------- android培训.java培训.期待与您交流! ---------- 函数: 什么是函数? • 函数就是定义在类中的具有特定功能的一段独立小程序. • 函数也称为方法. 函数的格 ...
- Java基础知识强化100:JVM 内存模型
一. JVM内存模型总体架构图: 方法区和堆由所有线程共享,其他区域都是线程私有的 二. JVM内存模型的结构分析: 1. 类装载器(classLoader) 类装载器,它是在java虚拟机中用途是 ...
- java虚拟机 jvm java堆 方法区 java栈
java堆是java应用程序最密切的内存空间.几乎所有的对象都存在堆中.java堆完全自动化管理,通过垃圾回收机制,垃圾对象会自动清理,不需要显式释放. 根据java垃圾回收机制的不同,java堆可能 ...
随机推荐
- [DDD]學習筆記 第15章 精煉(Distillation)
核心領域(Core-Domain) 為了使領域模型成為企業真正的資產, 模型中的關鍵核心部份需要足夠靈活和充分利用來創建應用程序的功能; 簡而言之, 核心領域是系統中最有價值的部份. 濃縮模型, 將最 ...
- ETL模型设计
传统的关系数据库一般采用二维数表的形式来表示数据,一个维是行,另一个维是列,行和列的交叉处就是数据元素.关系数据的基础是关系数据库模型,通过标准的SQL语言来加以实现. 数据仓库是多维数据库,它扩展了 ...
- IA-32e架构下的内核初始化内存管理
初级内存管理单元 关于内存的分页 以往的物理页是按照4KB进行分配和管理的, 而在Linux之后流行的就是2MB大小的物理页的分配和管理, 整个物理内存管理单元也是2MB物理页管理的 先获取基本的物理 ...
- Nginx 在Windows下搭建静态Web服务
简介 nginx [engine x] is an HTTP and reverse proxy server, a mail proxy server, and a generic TCP/UDP ...
- 斗鱼扩展--localStorage备份与导出(九)
之前我们都把数据 放在了 localStorage 里,但扩展一旦卸载,数据就会被清空, 在Console里备份,一次只能输出一条,小白操作起来很不方便,所以能不能 导入,导出文件来进行备份还原呢? ...
- Cordova各个插件使用介绍系列(七)—$cordovaStatusbar手机状态栏显示
在项目中发现Android和iOS在手机状态栏样式不一样,然后就查到有一个cordova插件可以解决这个问题 1.下载插件$cordovaStatusbar命令: cordova plugin add ...
- Azure 5 月新公布(二)
Azure 5 月新发布(二):CDN 图片处理功能, CDN Restful API, 新版 CDN 管理门户, 计量名称变更延期 Azure CDN 图片处理功能开放公共预览版 Azure CD ...
- 监控系统-mod-gearman
doc http://labs.consol.de/nagios/mod-gearman/ 安装 yum -y install gearmand-server-0.33-2.rhel6.x86_64. ...
- java:错误Error,异常Excepition
java中throw异常后代码还会继续执行吗 今天遇到一个问题,在下面的代码中,当抛出运行时异常后,后面的代码还会执行吗,是否需要在异常后面加上return语句呢? public void add(i ...
- JavaScript 获取 当前日期和三十天以前日期
//获取当前日期 var myDate = new Date(); var nowY = myDate.getFullYear(); var nowM = myDate.getMonth()+1; v ...