大话JMM

本文深入探讨Java内存模型(JMM)的基本概念,包括堆和栈的区别及其内部结构。重点介绍了堆中的年轻代、年老代及持久代的作用,并解析栈内存储的信息如局部变量、引用等。

    为啥题目叫《大话JMM》?因为JMM优秀的文章实在太多了,很多讲得灰常专业。对于我这个连本科毕业证都没拿到的家伙,就在自己的理解上整合一下自己的理解,可能讲得会比较通俗吧,还是原话,扯得离谱的地方尽管喷我,就是学习了。

    其实说到JMM主要都会讲到多线程里的主内存和工作内存,这两个名词大家肯定没少见,但它俩具体是什么东西,长啥样呢(身高、体重、三围)?因为这篇的主人公不是线程,所以先吊下胃口,先从堆和栈说起。

Heap:

    简单说,heap(堆),是所有的线程共享的空间,这就一下子和上面的主内存联系起来了。当然了,它和《数据结构》里面的大顶堆小顶堆里面的堆可不是一个东西,数据结构的堆是二叉树,而这里是一个连续的空间。我大二的时候就被这两个概念弄晕了很久,当然,栈(堆栈)在数据结构还是内存模型里都是一个德行的,这个放心。

    heap存的都是new出来的东西,可能有人会认为凡是java的对象都在堆里面,其实不是的。如果看过《java23种设计模式》,肯定知道什么是享元模式。说白了就是一个老被人用的东西就扔到容器里,然后谁用谁就引用它,免得new一堆一模一样的东西占空间(够精简吧)。String和基本类型就是用到的享元模式,比如int a=5;int b=5;这个5是存放在栈里面的,a和b都在引用,所以就省空间啦!同理,String a="5";String b="5";也是一样,因为不是new 出来的String,所以也是存放在栈中。只有String a=new String("5");才会放在堆里面,但这样它就失去了享元模式的特性了。

    heap虽然只放new的对象,但它也是蛮复杂的:

095946_voRI_1449976.jpg

这个被我涂鸦得很严重的图是http://my.oschina.net/u/436879/blog/85478上面的,不过说明基本上都标在图里面了,我也简单的说一下:

heap有年轻代、年老代和持久代三个部分。

年轻代:Eden+俩一模一样的Survivor,刚new的都是扔到Eden里面,Eden满了就会扔到一个Survivor里面,那个Survivor满就会扔到另一个里面。这两个Survivor没先后顺序,所以可能某个Survivor会同时存在刚扔进去和第二次被扔进去的对象。如果某个对象被进两个survivor过还没有被gc干掉,那就是它太尿性了,直接丢到年老代里。因为这说明这家伙后面要经常会被用到,为了不折腾,就扔到不容易被回收的年老代好了。

年老代:没啥说的,不容易被回收。

持久代:它对垃圾回收影响不大,放的也都是些static的和class的信息。正如图中涂鸦举的例子,如果会动态生成调用大量class时把它设置得大一点是比较明智的,大小通过-XX:MaxPermSize=<N>进行设置。

    堆的知识我知道的也就这点,后面就说栈了。

stack:

    多线程里每个线程有个缓存有个栈,栈是它自己才能用的,所以把IO流这些对象设成方法内的局部变量就没有线程不安全这个概念了,因为方法内的局部变量就是在线程的栈里面存着。

    栈里面存放的信息有:基本类型(局部变量)、引用(4字节的Heap内存地址)、代码、方法返回值、方法上下文。这里再“穿越”一下,从对象的存储形式说起。

图片出自http://m.blog.youkuaiyun.com/blog/tracker_w/12867977


101805_OWWq_1449976.jpg

这个就是一个对象在堆中的存储形式


101821_aJvd_1449976.jpg

如果带有继承,就会变成这样

101845_9u7i_1449976.jpg

    如果带有方法,那么每个类都会有一张虚表,它是用来存放类的所有方法的,这样只用存数据,方法查虚表,就不用每个对象都存放自己的方法了。

    之所以如此脱线的出了这3张图,其实就是为了具体的说明stack是用来存放代码和引用的。这里虚表指的方法就是存放在stack里面,而对象是在heap里,stack保留它的引用。

    stack中对对象的引用很重要,因为一旦被赋值为null,那么heap中的对象就是不可达的了。gc运行时采用有向图的方式遍历,发现不可达,那么这个东西就会被光荣的撵出内存。gc就是根据stack中的4字节地址扫描heap的。

    此外,再说一下stack的递归:其实递归是在栈中产生栈帧,每次递归都会放入一个栈帧,栈帧里的数据都是独立的,所以递归次数多了或者死递归就会出现overflow错误。当然,方法退出,那么这个栈帧就会销毁。


    这样,就算是把JMM和堆栈和GC扯到一起了,这东拼一块西拼一块的感觉大有《诚哥的逆袭》那杂乱无章的特点。不过希望对一些人会有帮助,如果有说得驴唇不对马嘴的地方,指出来好了,对我也是学习。





转载于:https://my.oschina.net/tdONEmadao/blog/220567

数据集介绍:垃圾分类检测数据集 一、基础信息 数据集名称:垃圾分类检测数据集 图片数量: 训练集:2,817张图片 验证集:621张图片 测试集:317张图片 总计:3,755张图片 分类类别: - 金属:常见的金属垃圾材料。 - 纸板:纸板类垃圾,如包装盒等。 - 塑料:塑料类垃圾,如瓶子、容器等。 标注格式: YOLO格式,包含边界框和类别标签,适用于目标检测任务。 数据格式:图片来源于实际场景,格式为常见图像格式(如JPEG/PNG)。 二、适用场景 智能垃圾回收系统开发: 数据集支持目标检测任务,帮助构建能够自动识别和分类垃圾材料的AI模型,用于自动化废物分类和回收系统。 环境监测与废物管理: 集成至监控系统或机器人中,实时检测垃圾并分类,提升废物处理效率和环保水平。 学术研究与教育: 支持计算机视觉与环保领域的交叉研究,用于教学、实验和论文发表。 三、数据集优势 类别覆盖全面: 包含三种常见垃圾材料类别,覆盖日常生活中主要的可回收物类型,具有实际应用价值。 标注精准可靠: 采用YOLO标注格式,边界框定位精确,类别标签准确,便于模型直接训练和使用。 数据量适中合理: 训练集、验证集和测试集分布均衡,提供足够样本用于模型学习和评估。 任务适配性强: 标注兼容主流深度学习框架(如YOLO等),可直接用于目标检测任务,支持垃圾检测相关应用。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值