‘壹’ java对象静态变量放在jvm的什么区域
从JVMS角度而言是在方法区(Method Area),对于特定的实现的话,例如Oracle HotSpot而言是在持久区(Permanent Area),HotSpot后续版本中会移除掉持久区的概念。 对于JVM内存区的划分可参考 不会,因为类的静态变量是此类的所有实例化对象全局共享的,即指向同一块内存,只要一个对象更改了静态变量,其他对象读到的都是更改后的静态变量,从设计上而言,也很容易理解,静态变量也称之为类变量,可以直接使用类名访问而不需要通过类对象访问,一楼所言有误。 这要看你的业务需求,原则上是尽量减少不必要的静态变量,对于一直常量类的话,你的变量就要包含静态变量了。
‘贰’ JVM内存布局及演变
-Xms1024m : 设置初始化内存分配大小,默认为本地内存的 1/64。
-Xmx1024m : 设置最大分配内存,默认为本地内存的1/4。
底层方法,与native方法相关。
线程私有,内存连续,存放8大基本类型+对象引用+实例的方法引用。
也叫PC寄存器,线程私有,保存当前执行指令的地址。
线程共享,内存不连续,存放对象实例。
-XX:+HeapDumpOnOutOfMemoryError : OOM
方法区是一个JVM规范上的逻辑概念,实际的位置根据不同JVM来看。
hotspot JVM虚拟机上将堆中的永久代作为方法区的一个存储实现,为的是方法区也可以用堆内存的GC垃圾回收机制,而不用重新针对方法区做GC操作,直接使用堆内存的GC就可以了。
存放静态变量(static)、常量(final)、类信息(Class,如构造方法、接口定义)、常量池。实例变量存在堆内存中,和方法区无关。
在Java7中永久代中存储的部分数据已经开始转移到Java Heap或Native Memory中了。比如,符号引用(Symbols)转移到了Native Memory;字符串常量池(interned strings)、类的静态变量(class statics)转移到了Java Heap,永久代中存放类和类加载器的元数据信息。
移除堆中的永久区,用占用本地内存的元空间(MetaSpace)来代替,存放类和类加载器的元数据信息。
符号引用没有存在元空间中,而是继续存在native heap中,这是两个方式和位置,不过都可以算作是本地内存,在虚拟机之外进行划分,没有设置限制参数时只受物理内存大小限制,即只有占满了操作系统可用内存后才OOM。
-XX:MetaspaceSize 来调整元空间初始大小,最大为本地内存大小。
感谢您的阅读,本文已同步到 我的个人博客 ,您的关注是对我最大的鼓励!
‘叁’ Java方法区和堆分别储存什么
静态变量、常量在方法区,所有方法,包括静态和非静态的,也在方法区。堆储存对象、数组、非静态变量。
‘肆’ jvm各个区的作用
JVM虚拟机包括:
1.类装载子系统
2.运行时数据区(内存模型)
堆(存放对象)
栈(线程)(具有先进后出的特性):每个线程启动时都会从栈中分配一块专属的内 存空间,用来存放每一个方法的栈帧内存空间。栈帧内存中包括以下几部分:
本地方法栈
方法区(元空间)
程序计数器:存放下一条指令所在单元的地址的地方
3.字节码执行引擎
将class文件放到方法区执行
修改程序计数器当前值
‘伍’ Java内存中的栈,堆和方法区的用法有什么不同
JAVA的JVM的内存可分为3个区:堆(heap)、栈(stack)和方法区(method)也叫静态存储区。
堆区:
存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令)
2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身
栈区:
每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中
2.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
3.栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
方法区:
又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。
2.方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。
‘陆’ JAVA中类中的方法存储在什么地方
类加载时 方法信息保存在一块称为方法区的内存中, 并不随你创建对象而随对象保存于堆中。可参考《深入java虚拟机》前几章。
另参考(他人文章):
如果instance method也随着instance增加而增加的话,那内存消耗也太大了,为了做到共用一小段内存,Java 是根据this关键字做到的,比如:instance1.instanceMethod(); instance2.instanceMethod(); 在传递给对象参数的时候,Java 编译器自动先加上了一个this参数,它表示传递的是这个对象引用,虽然他们两个对象共用一个方法,但是他们的方法中所产生的数据是私有的,这是因为参数被传进来变成call stack内的entry,而各个对象都有不同call stack,所以不会混淆。其实调用每个非static方法时,Java 编译器都会自动的先加上当前调用此方法对象的参数,有时候在一个方法调用另一个方法,这时可以不用在前面加上this的,因为要传递的对象参数就是当前执行这个方法的对象。
‘柒’ JVM 内存分哪⼏个区,每个区的作⽤是什么
从JVM的观点来看,它位于方法区域,对于具体的实现,如Oracle热点,它位于永久区域,持久性的概念在热点的后续版本中被删除。
JVM内存区域的分区不能被引用,因为类的静态变量是由类的所有实例化对象(即指向同一块内存)全局共享的。
只要一个对象改变静态变量,其他对象就读取改变的静态变量。
从设计的角度来看,静态变量也很容易理解。
也称为类变量,可以直接使用类名访问,而不需要通过类对象访问,第一层是错误的。
这取决于您的业务需求,原则上最小化不必要的静态变量。
对于常数类,变量包含静态变量。
‘捌’ java线程存放在jvm的哪个区域方法又存放在哪个区呢
聊到JAVA中的方法,大多数人对于方法存储在方法区还是栈区(虚拟机栈)是很迷茫的。其实方法是存在方法区的下面我们就细细说一下JVM中的 方法区 VS 栈区方法区:用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据,方法编译出的字节码也是保存在这
‘玖’ Java构造函数(方法)存储在jvm哪个内存里
存放到方法区当中;
new出来的是实例对象,实例对象才是存放在堆当中;
构造函数对应的是<init>方法,方法信息随着类加载器加载到方法区当中。
栈:
以栈帧为单位,存放的不是方法具体的结构,只是通常一个方法对应一个栈帧,对应的入栈出栈就是栈帧的入栈出栈。栈帧中有局部变量表,操作数栈,方法返回地址,动态链接。其中局部变量表存放局部变量,包括形参,非静态方法默认在第一个索引存放一个this变量;操作数栈用于操作局部变量表和一些值的运算,比如读取表中变量的值进行运算,或存放相应的值到局部变量表中;方法返回地址则是用于记录对应方法的下一条指令的地址;动态链接是符号引用变成的直接引用。
堆:
存放实例对象,在jdk7开始,还存放静态变量和字符串常量池
方法区:
存放类元信息,比如完整类名全称,public,abstract等修饰符,实现的接口有序列表等;方法信息,比如修饰符,返回类型等;JIT代码缓存,也就是被即时编译器编译后的热点代码,用于提高性能;域信息,也就是属性信息,比如修饰符,类型等;运行时常量池,字节码文件中常量池的运行时表现,类似符号引用的记录,不过蕴含的信息更为丰富,而且具有动态性。jdk6及以前,还存放静态变量,运行时常量池中还存放字符串常量池,到了jdk7则移到了堆中。
‘拾’ java中,静态方法被调用是,存储在内存的哪个区域是栈还是放大区还是两者都有
在JDK8之前,静态成员(静态变量和静态方法)都是存储在方法区(永久代)中的静态区中(这里指类被加载后,静态成员的存储位置)。但在JDK8之后,永久代被移除了,取而代之的是元空间(metaspace)。但元空间中存储的主要是.class文件的元数据信息,静态成员的存储位置由方法区转到了堆内存(heap)中。
不过,不管是JDK8,还是更早的版本中,静态方法的执行(不仅仅是静态方法,还有普通的成员方法)都是在栈内存(stack)中进行的。每个线程都会在栈内存中开辟一个栈,在调用方法时,对应的方法都会在执行这个方法的线程的栈中创建一个“栈帧”,栈帧中保存了局部变量表(基本数据类型和对象引用)、操作数栈、动态连接和返回地址等信息。等到方法执行完毕,栈帧被销毁,对应的内存也将被释放。