企业网站开发费是固定资产吗,徐汇做网站公司,网络营销是什么时候产生的,品牌网站建设 杭州说到Java中堆、栈和常量池#xff0c;首先还是看看他们各自存放的数据类型吧#xff01;栈#xff1a;Java的JVM的内存可分为3个区#xff1a;堆(heap)、栈(stack)和方法区(method)也叫静态存储区。堆区:(存放所有new出来的对象#xff1b;)1.存储的全部是对象#xff0c…说到Java中堆、栈和常量池首先还是看看他们各自存放的数据类型吧栈Java的JVM的内存可分为3个区堆(heap)、栈(stack)和方法区(method)也叫静态存储区。堆区:(存放所有new出来的对象)1.存储的全部是对象每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令)2.jvm只有一个堆区(heap)被所有线程共享堆中不存放基本类型和对象引用只存放对象本身栈区:(存放基本类型的变量数据和对象的应用对象(new出来的对象)本身并不存在栈中而是存放在堆中或者常量池中(字符串常量对象存放在常量池中))1.每个线程包含一个栈区栈中只保存基础数据类型的对象(比如int i1中1就是基础类型的对象)和自定义对象的引用(不是对象)而真实对象都存放在堆区中2.每个栈中的数据(原始类型和对象引用)都是私有的其他栈不能访问。3.栈分为3个部分基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。常量池存放基本类型常量和字符串常量。方法区:1.又叫静态区跟堆一样被所有的线程共享。方法区包含所有的class和static变量。2.方法区中包含的都是在整个程序中永远唯一的元素如classstatic变量名不是常量(它在堆栈中)。进一步解析(指数据共享时)对于栈和常量池中的数据可以共享(具有多个引用对象)对于堆中的对象不可以共享(一个引用对象)。 (指线程共享时)比如同一个进程的多个线程堆栈共享状况哪个描述正确线程共享堆但是每个线程有自己的寄存器和栈解析 线程占有的都是不共享的其中包括栈、寄存器、状态、程序计数器线程间共享的有堆全局变量静态变量主要指共享进程的资源进程占有的资源有地址空间全局变量打开的文件子进程信号量、账户信息。栈中的数据大小和生命周期是可以确定的当没有引用指向数据时这个数据就会自动消失。堆中的对象的由垃圾回收器负责回收因此大小和生命周期不需要确定具有很大的灵活性。而对于字符串来说其对象的引用都是存储在栈中的如果是编译期已经创建好(即指用双引号定义的)的就存储在常量池中如果是运行期(new出来的对象)则存储在堆中。对于equals相等的字符串在常量池中是只有一份的在堆中则有多份。关于方法区理解在一个jvm实例的内部类型信息被存储在一个称为方法区的内存逻辑区中。类型信息是由类加载器在类加载时从类文件中提取出来的。类(静态)变量也存储在方法区中。因为方法区是被所有线程共享的所以必须考虑数据的线程安全。假如两个线程都在试图找lava的类在lava类还没有被加载的情况下只应该有一个线程去加载而另一个线程等待。方法区的大小不必是固定的jvm可以根据应用的需要动态调整。同样方法区也不必是连续的。方法区可以在堆(甚至是虚拟机自己的堆)中分配。jvm可以允许用户和程序指定方法区的初始大小最小和最大尺寸。方法区同样存在垃圾收集因为通过用户定义的类加载器可以动态扩展Java程序一些类也会成为垃圾。jvm可以回收一个未被引用的(没有实例对象)类所占的空间以使方法区的空间最小。方法区存在类成员表的理解Java方法调用面临两个新的问题是方法重载和方法重写方法重载使用的技术叫符号毁坏方法重写的技术叫做动态派发。Java中的所有方法都支持重写要实现在运行时动态确定调用的具体方法就需要一张方法表这张方法表记录当前对象所对应的类含有的所有方法包括父类的方法。方法调用的时候需要从子类方法开始搜索这张表如果子类未找到就到父类找再父类。。。符号毁坏沿用了C的解决方法就是给方法重命名如method参数个数(args) 这样方法就唯一了。所以核心问题还是方法重写也就是动态派发也是java的性能瓶颈因为C只有virtual方法才会产生动态派发。要处理好动态派发一种可能的实现方式是专门开辟一个区单独管理所有方法可以按照稳定性对于该对象的所有方法(当然包括父类方法)进行稳定性排序使相同方法聚集在一起。当方法调用时在方法区搜索的时候一次定位到相同方法的位置的起始处不管第一个命中方法是父类还是子类也不管此处相同方法的个数始终执行第一个。作者寻寒链接https://www.zhihu.com/question/23599282/answer/25076568来源知乎著作权归作者所有转载请联系作者获得授权。举个例子吧Java代码String s1 china;String s2 china;String s3 china;String ss1 new String(china);String ss2 new String(china);String ss3 new String(china);对于基础类型的变量和常量变量和引用存储在栈中常量存储在常量池中。如以下代码Java代码int i1 9;int i2 9;int i3 9;public static final int INT1 9;public static final int INT2 9;public static final int INT3 9;对于成员变量和局部变量成员变量就是方法外部类的内部定义的变量局部变量就是方法或语句块内部定义的变量。局部变量必须初始化。形式参数是局部变量局部变量的数据存在于栈内存中。栈内存中的局部变量随着方法的消失而消失。成员变量存储在堆中的对象里面由垃圾回收器负责回收。如以下代码Java代码class BirthDate {private int day;private int month;private int year;public BirthDate(int d, int m, int y) {day d;month m;year y;}省略get,set方法………}public class Test{public static void main(String args[]){int date 9;Test test new Test();test.change(date);BirthDate d1 new BirthDate(7,7,1970);}public void change1(int i){i 1234;}对于以上这段代码date为局部变量i,d,m,y都是形参为局部变量daymonthyear为成员变量。下面分析一下代码执行时候的变化1. main方法开始执行int date 9;date局部变量基础类型引用和值都存在栈中。2. Test test new Test();test为对象引用存在栈中对象(new Test())存在堆中。3. test.change(date);i为局部变量引用和值存在栈中。当方法change执行完成后i就会从栈中消失。4. BirthDate d1 new BirthDate(7,7,1970);d1为对象引用存在栈中对象(new BirthDate())存在堆中其中dmy为局部变量存储在栈中且它们的类型为基础类型因此它们的数据也存储在栈中。 day,month,year为成员变量它们存储在堆中(new BirthDate()里面)。当BirthDate构造方法执行完之后d,m,y将从栈中消失。5.main方法执行完之后date变量testd1引用将从栈中消失new Test(),new BirthDate()将等待垃圾回收。