Java对象的内存(一)

前言

新人一枚,刚刚入门编程不久,各方面都在学习当中,博文有什么错误的地方,希望我们可以多多交流!

最近,在开发App后台过程中,需要将项目部署到云服务器上。而云服务器的内存大小却只有1G。要如何做到较为合理的内存使用,由此引发了我的一些关于内存方面的疑问:

  • 一个类的对象占内存多少?其大小由什么决定?
  • Java类中过长的方法会不会影响类的对象大小?
  • 将过长的方法封装会不会影响原来的运行速度?

一个或者多个Java对象的内存模型图

第一种比较简单的情况:
    public class Boy{  				 
         private String name;  
         private int weight;  
         public void play() {….}  

        public static void main(String[] args){  
                    Boy b = new Boy();  
                    b.play();  
         }  
    }  

这是一个简单的Java类,我们通过这个对象的创建、方法调用来简单了解Java对象的内存模型,如下图

上图的栈中每一个小方框代表一个栈帧,每当执行一个方法时,就会往JVM栈中压入一个栈帧。
而该栈帧用来保存参数、局部变量和一些其他的数据。

1)类的class文件会被读入JVM中的PermSpace中,为之创建一个java.lang.Class对象。当要在堆中创建实例对象时,会为该实例对象的class静态属性赋值

补充:什么是PermSpace?

是方法区中一块主要用来存放静态的类信息和方法信息,静态的方法和变
量,final标注的常量信息等等。

另外该区域的内存不会被GC回收

2)当使用Boy这个类时,JVM会先在PermSpace中寻找是否有对应的class文件,如果还未被加载到内存中,则系统会通过加载、连接、初始化来对该类进行初始化。

3)boy对象运行时就需要找到其实例对象的地址,这个地址由哈希编码,并记录在JVM的一张表上。而调用对象的非静态方法时,也会有个相对应的方法地址(该词仅为了易于表达)指向PermSpace中的方法。

4)当该对象的引用变量b调用方法play时,会通过堆中的该对象的方法地址,找到相对应的方法,并最终往JVM的栈中在压入一个栈帧。执行完成相对应的方法后直接弹出该栈帧

第二种多个同类类型的对象的情况:

1)当有多个同类类型的Java对象时,尽管各个对象都有一套自己的不同状态的成员变量,但是它们的方法地址都是指向的PermSpace中的该类的方法代码。当调用对象的非静态方法时,该情况和上述的第(4)点类似

posted @ 2016-12-06 17:00  auhnayuiL  阅读(1675)  评论(0编辑  收藏  举报