2022年从JVM内存管理的角度谈谈静态方法和静态属性和java对象引用与JVM自动内存管理 .pdf
《2022年从JVM内存管理的角度谈谈静态方法和静态属性和java对象引用与JVM自动内存管理 .pdf》由会员分享,可在线阅读,更多相关《2022年从JVM内存管理的角度谈谈静态方法和静态属性和java对象引用与JVM自动内存管理 .pdf(12页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、从 JVM 内存管理的角度谈谈静态方法和静态属性和 java 对象引用与JVM自动内存管理分类: JAVA 2010-08-04 11:17 1559 人阅读 评论(2) 收藏 举报jvmjavareferenceclassloader 编译器 applet试着从 JVM 的内存管理原理的角度来谈一下静态方法和静态属性的问题,不对的地方请指正。( JVM 的内存分为两部分:stack 和 heap : (code seg) (data seg)从硬盘 load 到 code seg 中 之后如下所述stack (栈)是 JVM 的内存指令区。 stack 管理很简单, push 一定长度字节的
2、数据或者指令,stack 指针压栈相应的字节位移;pop 一定字节长度数据或者指令,stack 指针弹栈。 stack的速度很快, 管理很简单, 并且每次操作的数据或者指令字节长度是已知的。所以 Java 基本数据类型, Java 指令代码,常量都保存在stack 中。heap (堆)是 JVM 的内存数据区。heap 的管理很复杂,每次分配不定长的内存空间,专门用来保存对象的实例。在heap 中分配一定的内存来保存对象实例,实际上也只是保存对象实例的属性值,属性的类型和对象本身的类型标记等,并不保存对象的方法(方法是指令,保存在stack中) ,在 heap 中分配一定的内存保存对象实例和对
3、象的序列化比较类似。 而对象实例在heap 中分配好以后, 需要在 stack 中保存一个4 字节的 heap 内存地址,用来定位该对象实例在heap 中的位置,便于找到该对象实例。由于 stack 的内存管理是顺序分配的,而且定长,不存在内存回收问题;而heap 则是随机分配内存,不定长度,存在内存分配和回收的问题;因此在JVM中另有一个GC进程,定期扫描heap ,它根据 stack中保存的 4 字节对象地址扫描heap ,定位 heap 中这些对象, 进行一些优化 (例如合并空闲内存块什么的),并且假设heap 中没有扫描到的区域都是空闲的,统统refresh(实际上是把stack 中丢
4、失了对象地址的无用对象清除了),这就是垃圾收集的过程。我们首先要搞清楚的是什么是数据,什么是指令?然后要搞清楚对象的方法和对象的属性分别保存在哪里?为了便于描述,我简单的统称:1)方法本身是指令的操作码部分,保存在stack 中;2)方法内部变量作为指令的操作数部分,跟在指令的操作码之后,保存在stack 中(实名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 12 页 - - - - - - - - - 际上是简单类型保存在stack 中,对象类型在stack 中保存地址
5、,在heap 中保存值);上述的指令操作码和指令操作数构成了完整的Java 指令。3)对象实例包括其属性值作为数据,保存在数据区heap 中。非静态的对象属性作为对象实例的一部分保存在heap 中,而对象实例必须通过stack 中保存的地址指针才能访问到。因此能否访问到对象实例以及它的非静态属性值完全取决于能否获得对象实例在stack 中的地址指针。先分析一下非静态方法和静态方法的区别:非静态方法有一个和静态方法很重大的不同:非静态方法有一个隐含的传入参数this,该参数是 JVM 给它的, 和我们怎么写代码无关,这个隐含的参数就是对象实例在stack 中的地址指针。因此非静态方法(在stac
6、k中的指令代码)总是可以找到自己的专用数据(在heap 中的对象属性值) 。当然非静态方法也必须获得该隐含参数,因此非静态方法在调用前,必须先 new 一个对象实例, 获得 stack 中的地址指针, 否则 JVM将无法将隐含参数传给非静态方法。而静态方法无此隐含参数,因此也不需要new 对象,只要class文件被 ClassLoader load进入 JVM 的 stack,该静态方法即可被调用。当然此时静态方法是存取不到heap 中的对象属性的。总结一下该过程: 当一个 class文件被 ClassLoader load 进入 JVM后,方法指令保存在stack中,此时heap 区没有数据
7、。然后程序技术器开始执行指令,如果是静态方法,直接依次执行指令代码,当然此时指令代码是不能访问heap 数据区的;如果是非静态方法,由于隐含参数没有值,会报错。因此在非静态方法执行前,要先new 对象,在 heap 中分配数据,并把stack 中的地址指针交给非静态方法,这样程序技术器依次执行指令,而指令代码此时能够访问到heap 数据区了。再说一下静态属性和动态属性:前面提到对象实例以及动态属性都是保存在heap 中的,而heap 必须通过 stack 中的地址指针才能够被指令(类的方法) 访问到。 因此可以推断出: 静态属性是保存在stack 中的,而不同于动态属性保存在heap 中。正因
8、为都是在stack 中,而 stack中指令和数据都是定名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 12 页 - - - - - - - - - 长的,因此很容易算出偏移量,也因此不管什么指令(类的方法),都可以访问到类的静态属性。也正因为静态属性被保存在stack 中,所以具有了全局属性。总结一下:静态属性保存在data seg 内存区,动态属性保存在heap 数据内存区。补充 :1.在 java 中有一个字符常量的池,专用来存储常量2.基本类型是保存在栈中,例如
9、: int a=9; 先在栈中寻找是否有这个值,有的话将引用指向它,没有的话在上面创建这个值,接着把引用指向它3. 栈的存取速度较快仅次于位于cpu 中的寄存器但位于其中的数据大小和生存期必须是确定的缺乏了灵活性一般用于存储声明的变量堆由于可动态分配内存使其速度慢于栈一般用于开辟对象空间还由于生存期不必事先告诉编译器事后得由gc收集Java中非静态方法是否共用同一块内存?将某 class 产生出一个instance 之后,此class 所有的instance field 都会新增一份,那么所有的instance method 是否也会新增一份?答案是不会,我们用field 表示字段,用meth
10、od 表示方法,那么加上static 区分后就有四种:class field:有用 static 修饰的 field class method :有用 static 修饰的 method instance field :没有用 static 修饰的 field instance method :没有用 static 修饰的 method 那么他们在内存中的表示为:class field:共用一块记忆体class method :共用一块记忆体instance field :随着每个instance 各有一块记忆体instance method :共用一块记忆体如果 instance metho
11、d 也随着 instance 增加而增加的话,那内存消耗也太大了,为了做到共用一小段内存,Java是根据 this 关键字做到的,比如:instance1.instanceMethod(); instance2.instanceMethod(); 在传递给对象参数的时候,Java编译器自动先加上了一个this参数, 它表示传递的是这个对象引用,虽然他们两个对象共用一个方法,但是他们的方法中所产生的数据是私有的,这是因为参数被传进来变成call stack 内的 entry ,而各个对象都有不同call stack,所以不会混淆。其实调用每个非static 方法时, Java编译器都会自动名师资
12、料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 12 页 - - - - - - - - - 的先加上当前调用此方法对象的参数,有时候在一个方法调用另一个方法,这时可以不用在前面加上this 的,因为要传递的对象参数就是当前执行这个方法的对象。为什么静态方法中不能调用非静态方法?这是因为静态方法直接跟class相关, 调用此方法的时候是类直接调用的,而不是对象, 所以 Java编译器就没有对象参数可以传递,这样,如果你在静态方法内部调用非静态方法,那么Java编译器怎么判断这个
13、非静态方法是哪个对象调用的?对吧,所以Java编译器就会报错,但是也不是绝对的,Java编译器是隐式的传递对象参数,那么我们总可以显示的传递对象参数吧,如果我们把某个对象的引用传递到 static 方法里,然后通过这个引用就可以调用非静态方法和访问非静态数据成员了。解析 Java对象引用与JVM 自动内存管理对象引用应用程序设计接口是JDKTM1.2中新定义的。该应用程序设计接口允许应用程序以对象引用的方式与JVM 的内存管理器进行交互。当应用程序需管理大量内存对象或者在新的 Java对象创建之前需删除原有对象时,Java对象引用应用程序设计接口具有相当大的用途,例如: 基于 Web 的应用程
14、序常常要求显示大量图片,当用户离开某一Web 页时,往往不能确定是否能够顺利的返回。在这种程序中,应用Java对象引用API可以创建这样一个环境,即当堆内存以最小程度运行时,内存管理器创建对象。当用户返回时, 应用程序就会重新载入已经创建的图片。 应用对象引用队列可以创建这样一个环境,当通过对象引用获得某一对象时,应用程序得到通知。 然后, 应用程序就可以对相关对象进行清除操作,同时使这些对象在内存管理器中合法化。内存管理器的工作机制下面将首先介绍未嵌入引用对象时内存管理器的工作机制,然后讨论引用对象加入之后Java堆发生的变化。内存管理器的作用就是识别程序中不再使用的对象,并且回收其内存。一
15、个 Java应用程序由一系列线程组成,每个线程执行一系列方法,而每个方法通过参数或局部变量来引用对象。这些引用属于引用集合中的一部分,直接进入应用程序。另外,名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 12 页 - - - - - - - - - 引用集合中还包括类库中定义的静态引用变量,以及通过Java本地接口 (JNI)API获得的引用。引用集合中的所有引用对象都可以被当前应用程序获取,而不必被回收。同样地,这些对象可能包含对其它对象的引用,也可以被应用程序获取,
16、依此类推。 Java堆中的其它对象视为不可获取的,而所有这些不可获取的对象在内存管理中也是合法的。如果一个不可获取的对象使用finalize()方法,任务就交给了对象所调用的收尾器(finalizer ) 。在内存回收期间,不具有收尾器的不可获取对象和已经调用收尾器的对象被简单回收。内存回收的算法是不断变化的,共性的方面是从引用集合中识别可获取的对象以及回收被其它对象占据的内存空间。加入引用对象之后的引用与常规引用的区别在于,引用对象中的引用专门由内存管理器来处理。 引用对象封装了其它一些对象的引用,我们称之为指示对象。在引用对象创建的同时,也就定义了该引用对象的指示对象。根据应用程序要求,对
17、象可以是强引用(strong references) 、次引用( soft references) 、弱引用( weak references) 、虚引用( phantom references )的任意组合。为了确定对象的可获取程度, JVM 内存管理器从引用集合出发遍寻堆中所有到对象的路径。当到达某对象的任意路径都不含有引用对象时,则称该对象具有强获取能力;当路径中含有一个或几个引用对象时, 根据内存管理器所查询的引用对象的类型分别归为次获取、弱获取、虚获取。另外,对象引用API中还定义了引用对象队列(java.lang.ref.ReferenceQueue) ,这是内存管理器对引用对象进
18、行管理的一种简单数据结构。值得注意的是, 在进行引用对象定义时,要求 phantom reference 对象必须产生于一个引用对象队列,而soft reference 和 weak reference 对象则无此限制,如:ReferenceQueue queue = new ReferenceQueue(); PhantomReference pr = new PhantomReference(object, queue); Soft References 应用实例下面以在基于web 的应用程序中使用soft references 为例,来说明Java对象引用与JVM的内存管理器进行交互的原
19、理。当用户打开某一web 页时, applet 代码获得图片并且得到显示。如果在代码中同时创建名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 12 页 - - - - - - - - - 了该图片对象的soft references,那么当用户离开该web 页时,内存管理器对图片所分配的内存是否回收做出选择。当用户返回该web 页时,在 applet 代码中使用SoftReference.get方法就会得到图片才内存中是否仍存在的消息。如果在内存管理器中未创建该图片,在w
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 2022年从JVM内存管理的角度谈谈静态方法和静态属性和java对象引用与JVM自动内存管理 2022 JVM 内存 管理 角度 谈谈 静态 方法 属性 java 对象 引用 自动
链接地址:https://www.taowenge.com/p-27297633.html
限制150内