new一个Objectios 对象占用内存多少内存

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
您的访问请求被拒绝 403 Forbidden - ITeye技术社区
您的访问请求被拒绝
亲爱的会员,您的IP地址所在网段被ITeye拒绝服务,这可能是以下两种情况导致:
一、您所在的网段内有网络爬虫大量抓取ITeye网页,为保证其他人流畅的访问ITeye,该网段被ITeye拒绝
二、您通过某个代理服务器访问ITeye网站,该代理服务器被网络爬虫利用,大量抓取ITeye网页
请您点击按钮解除封锁&new对象的时候,传进去一个对象的引用,内存是怎样的_java吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:543,674贴子:
new对象的时候,传进去一个对象的引用,内存是怎样的收藏
A a = new A();B b = new B(a);A,B都有相应的构造方法。。这时候对象b指向哪里呢
java上海北大青鸟于达校区专注java,免试入学,专科保底,学历+技能,包就业!喜迎新春,更有一大拨免费试听课程来袭,点击预约试听名额~北大青鸟于达校区
b 指向 B 类的一个实例啊
两个堆对象了,别被有参的迷惑了。
堆内存里面调吧
我想了下,终于看懂你的“为什么thread方法里,传的参数非要是runnable的对象啊 ”是什么意思了。eg:Ticket tickets = new Tickets();Thread t1 = new Thread(tickets);Thread t2 = new Thread(tickets);Thread t3 = new Thread(tickets);你说的是Thread为什么要传参是吧(怎么说成Runnable呢?)?那我问你,你多线程,你不把你要实现的那个线程放进去,怎么多线程?再不懂可以按着Ctrl然后点击Thread进去,看看Thread是怎样的。从下图中看到,name是参数,就是线程的名字。再看看另一个情况,无参的:从翻译中可以看出,他仍然是新建一个线程,但强调,新建,这个新的线程并不是我们想要的,所有,当你要对某一个对象实现多线程的时候,都要把这个线程名传进去。
对象b引用了一个新的B类对象而在构造这个新对象的时候调用了B类的public B(A a_gived)
这个构造函数这个构造函数需要一个A类的对象作为参数而构造函数用这个对象做什么要看构造函数的内容b=new B(a)并不会使变量b引用对象a或者引用根据对象a生成的一个新的对象(复制品)Thread对象是一个线程线程要执行的内容放在Runnable接口的run(
)方法中Thread对象本身就实现了Runnable接口如果继承Thread类重写run(
)方法就可以在生成的子类对象上直接运行线程意即一个线程必须调用某个实现了Runnable接口的类的对象的run( )方法这个对象可以是Thread类或子类的对象本身或者其他实现了Runnable接口的类的对象而用后一种必须告诉线程要执行哪个对象的run( )Thread类的public Thread( Runnable target )构造方法就完成了这个任务所以Thread t1 = new Thread(tickets)就是声明一个Thread类的变量t1t1引用一个线程对象这个线程对象要执行的是tickets这个对象的run( )方法最后一点,java并没有规定一个Runnable的对象只允许一个线程调用它的run( )方法所以同一时间可能有多个线程调用同一个对象的run( )方法
不管是Runnable也好,还是Thread也好。都要启动strart方法,以达到线程的交互.但是Runnable没有strat()方法,只有Thread才有strart()方法.Runnable的实现类要想启动线程调用run方法,只能通过构造一个新的Thread把实现类的对象交给Thread来启动线程。
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或new一个Object对象占用多少内存 - 编程当前位置:& &&&new一个Object对象占用多少内存new一个Object对象占用多少内存&&网友分享于:&&浏览:33次new一个Object对象占用多少内存?
Java的自动内存管理机制(automatic storage management system known as a garbage collector)省却了很多编码工作,大大地提高了Java的生产力,而且JVM的性能也越来越好,特别是G1的出现,改善了垃圾回收中stop the world的状况。
也许很多人都没有考虑过这个问题,new一个Object对象到底占用多少内存呢( Object obj = new Object() )?
这里很明确的是obj是一个指向对象的引用(reference - there are three kinds of reference types: class types,array types, and interface types),引用的长度决定了Java的寻址能力,32位的JDK是4字节,64位的JDK是8字节。
因为obj对象没有任何数据(field),会在堆上为它分配空间吗?如果分配空间,里面存储了什么内容?
以面向对象的思维来分析,对象封装了数据和行为,是一个统一的整体,虽然obj对象没有数据,但是有行为(Object类定义了12个方法)。当我们执行完new操作后,obj的值为堆内存的地址,既然obj都指向一块内存了,说明是会在堆上为其分配空间的。
那么分配的空间有多大,存储了什么内容呢?在The Java Virtual Machine Specification Java SE 7 Edition和The Java Language Specification Java SE 7 Edition里面没有找到相关的描述,这很可能是属于JVM实现自由控制的范畴了。我们可以利用JDK自带的工具jvisualvm.exe来查看分配的空间有多大。为了方便在jvisualvm中查看对象占多少内存,这里使用一个私有的静态内部类EmptyObject来替代Object,因为类定义为空,所以可以等同对待EmptyObject和Object。
* 构造一个无任何字段的空对象占多少内存
* @author 杨尚川
public class EmptyTest {
public static void main(String[] args) throws InterruptedException{
//加到集合中,使垃圾无法回收
List&EmptyObject& emptys = new ArrayList&&();
for(int i=0;i&100;i++){
emptys.add(new EmptyObject());
//打开jvisualvm,查看EmptyObject的大小为16字节
Thread.sleep(60*1000);
private static class EmptyObject{}
我们在这里面通过new不同的对象数(for循环次数),来分析内存占用,new 1个对象是16字节,new 2个对象是32字节,new 100个对象是1600字节,通过很多次的尝试,我们从jvisualvm里面可以看到 字节数=对象数*16 ,我们有理由相信对象数跟字节数的线性关系。从这里可以看出,jvisualvm显示的内存占用跟引用的4字节或8字节是没有关系的,也就是说,jvisualvm显示的是堆内存占用,这也很好理解,毕竟所有引用的字节占用是固定的。8字节是引用,16字节是堆内存,总共是8+16=24字节,所以new一个Object对象占用8+16=24字节(64位JDK)。
如果JDK是32位,按如上分析方法可知new一个Object对象占用4+8=12字节(32位JDK),如下图所示:
64位JDK:32位JDK:
那么分配的16字节(8字节)的堆内存中存储了什么内容呢?当我们Object obj = new Object();的时候,在栈内存中有一个引用obj,他可能是32位也可能是64位,obj实质只是一个内存地址,那么当我们调用obj.xxx()的时候,JVM怎么知道obj是哪个类的实例呢?所以,可以大胆地推测,obj对象的16字节(8字节)的堆内存中记录了对象属于哪个类的信息,问题是这16字节(8字节)的结构是什么样的?不清楚!
不过我们仍然可以大胆地猜测一下,通过上面的64位和32位的堆内存大小对比分析发现,堆内存分配的大小是引用的两倍,上面我们已经猜测堆内存中会记录对象是哪个类的实例,如何记录呢?因为类对象是放置在方法区的,类对象本身也是一个对象,因此可以通过一个引用指向它,所以堆内存有可能就是放置了两个引用,指向两个对象。分析到这里,事情就比较明朗了,堆内存中可能就放置了两个内存地址,一个指向EmptyObject.class(在实验代码中用EmptyObject来代替Object),一个指向什么呢?不清楚!
在Inside the Java 2 Virtual Machine 2nd by Bill Venners的5.3.5中有这么一段描述:
The Java virtual machine specification is silent on how objects should be represented on the heap. Object representation--an integral aspect of the overall design of the heap and garbage collector--is a decision of implementation designers.
好了,事情最终清楚了,JVM规范并没有规定Java对象在堆中是如何表示的,对象的表示是堆和垃圾收集器的整体设计的一个组成部分,这是由JVM实现的设计师来决定的。 因此,如果我们真的想搞清楚对象是如何表示的,那么需要查询SUN JDK或是其他JVM实现的设计文档。
我们研究new一个Object对象占多少内存可能没什么实际意义,因为我们在编程的时候就可以确定对象树,基本可以确定对象大小,除了变长字段,当然,变长字段我们一般也会有长度限制。所以我们真正关心的是所有数据最终的大小,也就是数据库的大小。
面向对象的分析、设计和编程都把“封装”奉为圭臬,“分层”更是架构设计中至关重要的设计准则。因为只有这样,才能实现基本的解耦、让协作分工成为可能,满足工业要求的最大化生产力的最终目标。
那么这种没有什么实际意义的问题为什么要研究呢?我觉得只能用三个字来形容:好奇心。好奇心是驱使我们研究技术的强大推力,当我们工作了很多年,尤其是在不重视技术的公司,我们对技术还有激情吗?保持一颗敏感好奇的心,也许技术之路可以走的更长更远。
这篇文章的重点是展示一种分析问题的思路,要大胆猜测,小心求证,追本溯源,引经据典。求证方式:查找标准规范、查找经典权威书籍、自己做实验、查找源代码等。
[size=large]8字节的引用这个毋庸置疑,但是引用应该是分配在线程栈内存里的,不在堆内存里。jvisualvm显示的16字节应该是指堆内存里占用16个字节吧。[/size]
永志_爱戴 写道[size=large]8字节的引用这个毋庸置疑,但是引用应该是分配在线程栈内存里的,不在堆内存里。jvisualvm显示的16字节应该是指堆内存里占用16个字节吧。[/size]没错你分析的对,new 1个对象是16字节,new 2个对象是32字节,new 100个对象是1600字节,我们从jvisualvm里面可以看到对象数跟字节数的线性关系,从这里可以看出,jvisualvm显示的内存占用跟引用的4字节或8字节是没有关系的,也就是说,jvisualvm显示的是堆内存占用,这也很好理解,毕竟所有引用的字节占用是固定的。
你既然猜想堆中存了两个地址,并且一个是Object.class,那另一个应该就是EmptyObject.class吧。很犀利的眼光,为了方便在jvisualvm中查看对象占多少内存,这里使用一个私有的静态内部类EmptyObject来替代Object,因为类定义为空,所以可以等同对待EmptyObject和Object。
想起了我自己之前研究的一个问题:一个1.2G的文件读到内存塞进容器里,结果内存爆了,也是因为数据在变成对象装入容器的过程中占用了比直接二进制编码入操作系统更大的内存编写正确的程序往往比一般人想象的难度要大的多,很多时候,程序是碰巧能运行,尤其是在多线程的情况下。
12345678910
12345678910
12345678910 上一篇:下一篇:文章评论相关解决方案 12345678910 Copyright & &&版权所有为什么要用new来建立一个对象
为什么要用new来建立一个对象
我看很多人写的代码都喜欢这样写(示例)MyClass* & pc & = & new & MyClass();pc-& doSome();...delete &为什么非要去new呢?而且这样很容易忘记最后delete。为什么不按照下面这样呢?MyClass &c.doSome();....我觉得这样很好阿,而且不需要delete。难道第一种写法有什么特别的好处吗?看到很多代码都是第一种写法。谢谢。答:& & &指针在传值和多态使用上比较安全。指针才是王道。。。 内存管理,多态。。。MyClass &c.doSome();---------------------------静态分配内存,在生成程序的时候已经确定它的内存如何分配MyClass* & pc & = & new & MyClass();pc-& doSome();delete &---------------------------动态分配内存,可以在程序运行的时候来决定如何分配,这样可以大大减少内存的浪费。而且,C++ & 的一个重要特性--多态,是通过指针或者引用来使用的。如果用静态内存分配方式,无法使用。例如:class & A{public:virtual & void & print() & { & std::cout & & & & "A::print()\n "; & }};class & B{public:virtual & void & print() & { & std::cout & & & & "B::print()\n "; & }};A & *p & = & new & B; & & // & 基类 & A & 的指针,可以指向 & 派生类 & B & 的对象p-& print(); & & & & // & B::print()// & 因为函数 & print() & 在基类 & A & 里面是 & virtual & 函数,同时在派生类 & B & 里面被修改过,// & 所以这里使用的是派生类 & B & 的 & print(),而不是基类 & A & 的 & print()如果 & A & 里面的 & print() & 不是 & virtual & 又或者它虽然是 & virtual & 但在 & B & 里面没有被改写,那么p-& print(); & & & & // & 使用的是 & A::print()如果用静态内存分配方式,则:A & & & & a.print(); & & // & 只能用 & A::print()B & & & & b.print(); & & // & 只能用 & B::print()不会有:A & *p & = & new & B;p-& print(); & & & & & & // & 这里究竟是 & A::print() & 还是 & B::print(),要看 & print() & 的性质这些东西书上都有说的。建议多看看我认为主要是作用域上的差别,一般能不用new,我都不用new的。至于多态和函数参数,都不是问题:多态可以这样用:B &A* & p & = & &b;p-& dosomething();传参数也是一样:函数定义:void & fn(B* & b);调用:fn(&b);或者这样定义:void & fn(B& & b);调用:fn(b);&用new是在堆上申请空间,堆的空间跟物理内存大小有关。而静态的声明是在栈上申请空间。栈的大小有限制。
发表评论:
馆藏&10281
TA的推荐TA的最新馆藏[转]&

我要回帖

更多关于 一个对象占用的内存 的文章

 

随机推荐