Jvm方法区以及static的内存分配图
前面的几篇都没有太明确地指出 方法区 是什么?现在通过一些资料的收集和学习,下面做一些总结
什么是方法区:
方法区是系统分配的一个内存逻辑区域,是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.构造代码块是什么?把所有构造方法中相同的内容抽取出来,定义到构造代码块中,将来在调用构造方法的时候,会去自动调用构造代码块。构造代码快优先于构造方法。
转载自:https://blog.csdn.net/Wang_1997/article/details/52267688
Jvm方法区以及static的内存分配图的更多相关文章
- Java基础-方法区以及static的内存分配图
转载自: https://blog.csdn.net/Wang_1997/article/details/52267688 前面的几篇都没有太明确地指出 方法区 是什么?现在通过一些资料的收集和学习, ...
- java虚拟机 jvm 方法区实战
和java堆一样,方法区是一块所有线程共享的内存区域,用于保存系统的类信息,类的信息有哪些呢.字段.方法.常量池.方法区也有一块内存区域所以方法区的内存大小,决定了系统可以包含多少个类,如果系统类太多 ...
- JVM 方法区内存扩大 以及开启GC
因为应用使用了OSGi框架,<深入理解JAVA虚拟机>中对使用OSGi时可能产生的方法区溢出有所描述 第一部分: 第二部分 可见,OSGi会动态生成大量Class,在OSGi中,即使是同一 ...
- jvm 方法区
方法区在一个jvm实例的内部,类型信息被存储在一个称为方法区的内存逻辑区中.类型信息是由类加载器在类加载时从类文件中提取出来的.类(静态)变量也存储在方法区中. jvm实现的设计者决定了类型信息的内部 ...
- [转]JVM 内存初学 (堆(heap)、栈(stack)和方法区(method) )
这两天看了一下深入浅出JVM这本书,推荐给高级的java程序员去看,对你了解JAVA的底层和运行机制有比较大的帮助.废话不想讲了.入主题: 先了解具体的概念:JAVA的JVM的内存可分为3个区:堆(h ...
- JVM 内存初学 堆(heap)、栈(stack)和方法区(method)
这两天看了一下深入浅出JVM这本书,推荐给高级的java程序员去看,对你了解JAVA的底层和运行机制有比较大的帮助.废话不想讲了.入主题:先了解具体的概念:JAVA的JVM的内存可分为3个区:堆(he ...
- 转:JVM 内存初学 (堆(heap)、栈(stack)和方法区(method) )
原文地址:JVM 内存初学 (堆(heap).栈(stack)和方法区(method) ) 博主推荐 深入浅出JVM 这本书 先了解具体的概念:JAVA的JVM的内存可分为3个区:堆(heap).栈( ...
- JVM内存初学 堆、栈、方法区
转自: http://www.open-open.com/lib/view/open1432200119489.html 这两天看了一下深入浅出JVM这本书,推荐给高级的java程序员去看,对你了解J ...
- JVM 内存初学 (堆(heap)、栈(stack)和方法区(method) )(转载)
想想面试的时候很多会问jvm这方面的问题虽然还是菜鸟不太能用到现在但是还是了解一下, 找资料的时候看见个大佬写的很好转载到这方便以后自己复习和给大佬做宣传 以下为大佬的博客原文: 这两天看了一下深入浅 ...
随机推荐
- Nginx——1.基础知识
Nginx——1.基础知识 作为高速.轻量.高性能等优点集于一身的服务器,Nginx在近些年迅速发展并不断扩大市场份额,甚至在最近其市场份额一举超过微软的IIS,跃身到第二位,仅次于Apache. 但 ...
- vue原理实现
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- ceph数据自动均衡程序
声明:程序基于ceph0.94.x制作 前言: ceph数据自动均衡,为了解决新集群搭建完成和添加新的节点后,不同或者相同容量的磁盘上面pg的分布不均衡,导致集群使用率达不到理想的标准 调整前准备: ...
- Python发送邮件代码
Python发送带附件的邮件代码 #coding: utf-8 import smtplib import sys import datetime from email.mime.text impor ...
- 数据结构11: 栈(Stack)的概念和应用及C语言实现
栈,线性表的一种特殊的存储结构.与学习过的线性表的不同之处在于栈只能从表的固定一端对数据进行插入和删除操作,另一端是封死的. 图1 栈结构示意图 由于栈只有一边开口存取数据,称开口的那一端为“栈顶”, ...
- beego 连接postgres
package main import ( "fmt" "github.com/astaxie/beego/orm" "mybee/models&qu ...
- pm2 启动后台 node js
1,安装node js 参看:https://www.cnblogs.com/wf-l5201314/p/9229974.html 2,pm2安装(安装环境linux / os) 命令:npm ins ...
- 斑马条码打印机通过js post 打印
<html lang="zh-ch"><head> <meta charset="utf-8"> <meta ht ...
- JavaScript中使用ActiveXObject操作本地文件夹的方法
转载地址 http://www.jb51.net/article/48538.htm 在Windows平台上, js可以调用很多Windows提供的ActivexObject,本文就使用js来实 ...
- 爬虫(GET)——爬取多页的html
工具:python3 目标:将编写的代码封装,不同函数完成不同功能,爬取任意页数的html 新学语法:with open as 除了有更优雅的语法,with还可以很好的处理上下文环境产生的异常. # ...