`

一段垃圾程序引出的Java垃圾回收机制

 
阅读更多
出来混的,总是要还的。看来做软件,写代码也是这样啦!这篇应该算是Java编程思想阅读笔记的续集,由一段写得非常垃圾的程序引起,牵出了垃圾回收等一些相关知识,至于原来程序出现的堆溢出(java.lang.OutOfMemoryError: Java heap space)原因,还得继续寻找。下面先看一段类似的垃圾代码:


首先说明代码,一个线程类型(NewThread),就是在死循环中不停的创建新对象,当然里面标识了线程号;另一个类就是main所在了,循环创建一定数量的NewThread对象,然后启动。初衷是想建立一定数量的线程,让线程循环执行,结果其实忽略了几个问题:
1.线程对象是在循环体中创建的,那其作用域的问题;
2.线程创建完成后,main函数也就是主线程运行完毕了
针对第一个问题就是今天记录的主题,Java中的垃圾回收机制。先从《Java编程思想》中汲取,有C/C++的基础,有时候并不见得是好事,在C/C++中总会想着函数返回时内存的回收,动态申请的内存要主动释放,而且new申请的对象会在释放时自动调用析构函数;而在Java中不用过多的考虑,但是也放心不下,垃圾收集器什么时候,回收怎样的对象占用的内存呢?Java是在堆上分配对象,采用一些回收方法,目标是把不会再用到的对象内存释放掉,当然它没有那么聪明,知道你以后不会再用哪些,一般便于理解说明的是“引用计数”方式,即每个对象都含有一个引用计数器,当有引用指向对象时,引用数加1,当引用离开作用域或被置null时,引用计数减1,当运行的后台回收线程发现某个对象引用为0时,就释放其内存,这里有个问题是如果有循环引用(还有我上面那个程序你会发现问题),那么就无法正确释放内存;因此又有了“停止——复制”方式,这种方式是先暂停程序的运行,然后将所有存活的对象从当前堆复制到另一个堆中,没有被复制的全部都是垃圾,而且这种方式能够使新堆保持紧凑,但是这种方式消了较低,一方面暂停了程序运行,至少比实际需要多一倍的空间,另一方面,在程序进入稳定状态后,可能只有少量或没有垃圾,如此垃圾回收就显得浪费;其它还有些方式,可以查看参考【1】。
那么如此,就有个疑问了,我的main所在的类中声明的线程类型对象,是在for循环当中,相当于每次都离开了作用域,会不会for循环完之后就都退出了呢?而且在C/C++中,main的退出意味着程序的退出,那么这个程序是不是才刚创建完所有线程就退出了呢?我们再看Java的守护线程和非守护线程,
守护线程通常是由虚拟机自己使用的,比如执行垃圾收集任务的线程;
Java程序可以把它任何创建的线程标记为守护线程;
Java初始线程(即开始于main方法的线程)是非守护线程;
只要还有任何非守护线程在运行,那么这个Java程序也在运行,即这个JVM实例还存活着;当JVM中的所有非守护线程都终止时,JVM实例将自动退出;(参考【2】)

好了,顺带的第2个问题也知道了,那么堆溢出是怎么回事呢?貌似这里不会产生啊,可以看到其使用情况(VisualVM好用的软件啊)截图如下:


垃圾回收器及时收回内存。有无休眠直接影响CPU的占用。后图多了个软引用,可以看到回收的延迟。

从代码中还看到使用了SoftReference,这个其实就是三种引用:弱引用、软引用、虚引用;大概意思就是弱引用可以再对象置null时和垃圾回收之前延长点时间再回收,和finalize类似,只是finalize中包含了回收前执行的方法(主要是在调用了C/C++中的代码要执行的内存释放);软引用多用于缓冲区,在内存告急时才会被释放;虚引用则是主要用来跟踪对象被垃圾回收的活动,和引用队列(ReferenceQueue)联合使用,在回收前做点操作(上面只是试了软引用,从截图也能看出些东西来,详细的可以看参考3)。但是这样堆溢出还是没有找到原因,还是继续寻找吧。
参考:
【1】详细介绍Java垃圾回收机制 http://www.cnblogs.com/laoyangHJ/articles/java_gc.html
【2】Java虚拟机学习笔记(三)Java虚拟机 http://diecui1202.iteye.com/blog/606046
【3】Java基础 之软引用、弱引用、虚引用 http://www.cnblogs.com/blogoflee/archive/2012/03/22/2411124.html
分享到:
评论

相关推荐

    java程序设计教程

    本书从计算机软件设计员的角度出发,结合软件设计语言的发展趋势,就 Java 语言的应用与面向对象 ...从而引出 Java 面向对象程序设计思想。本书从 Java 语言和面向对象程序设计方法相结合入手,以大量实例

    Java 垃圾回收新算法刍探

    由Java语言与C/C++对象在内存管理方式的不同,引出了Java语言的优势技术——垃圾处理技术。通过对GC工作原理的阐述及对一些传统的垃圾收集器的分析,提出了一种新的垃圾处理算法,一定程度上改善和提高了Java垃圾...

    Java基础教案\JAVA精讲入门

     一个Java程序的开发过程  一个简单的Java应用程序的开发过程  什么是JSP 授课目的:  掌握Java语言的特点  掌握环境变量的配置  掌握Java程序的开发过程  了解JSP技术 授课重点及难点:  建立Java...

    《Java程序设计》教学活动设计.doc

    《Java程序设计》教学活动设计 第一讲 基本活动安排: 1. 介绍课程内容,上课方式,上课时间和地点。明确考核方式和学习要求。 2. 要求学生注册登录虚拟学习社区: htp://...

    JAVA反射机制详解视频

    (类的加载概述和加载时机) (类加载器的概述和分类) (获取class文件对象的三种方式) ...(通过反射写一个通用的设置某个对象的某个属性为指定的值) (通过用户的增删改查和学生的登录注册引出中介) (动态代理的概述和实现)

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    第1章 让自己的第一个Java程序跑起来 2 教学视频:19分钟 1.1 想要用Java改变这个世界吗? 2 1.1.1 Java有什么优势? 2 1.1.2 Java在哪儿? 3 1.2 准备好开始Java之旅 3 1.2.1 下载JDK 4 1.2.2 安装JDK 5 ...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    第1章 让自己的第一个Java程序跑起来 2 教学视频:19分钟 1.1 想要用Java改变这个世界吗? 2 1.1.1 Java有什么优势? 2 1.1.2 Java在哪儿? 3 1.2 准备好开始Java之旅 3 1.2.1 下载JDK 4 1.2.2 安装JDK 5 ...

    EAS模板引入引出

    EAS基础资料的引入引出流程和代码的实现应该对大家有用,共享一下。

    高中历史之历史百科宋刻本越绝书引出的一段公案素材

    高中历史之历史百科宋刻本越绝书引出的一段公案素材

    Java双缓冲技术.doc

    本文从J2SE的一个再现了屏幕闪烁的Java Appilication简单动画实例展开,对屏幕闪烁的原因进行了分析,找出了闪烁成因的关键:update(Graphics g)函数对于前端屏幕的清屏。由此引出消除闪烁的方法——双缓冲。双缓冲...

    Java 高级特性.doc

    5.在JAVA的程序中,我经常性的看到字符前面有@这种标志的符号.这个就叫做注解! 下面是使用 @SuppressWarnings 来取消 deprecation 警告的一个例子: public class Test { @Deprecated //在eclipse下运行的时候,...

    SpringBoot揭秘-快速构建微服务体系

    本书以微服务的基本概念介绍性开篇,逐步引出Java平台下打造微服务的利器SpringBoot微框架。书中从SpringBoot微框架的“出身”开始,循序渐进,为大家剖析SpringBoot微框架的设计理念和原理,并对框架的重点功能和...

    《世界地图引出的发现》思考题一.ppt

    《世界地图引出的发现》思考题一.ppt

    Java IO 体系.md

    Java IO 体系 - Java IO 体系 ...Java IO 是一个庞大的知识体系,很多人学着学着就会学懵了,包括我在内也是如此,所以本文将会从 Java 的 BIO 开始,一步一步深入学习,引出 JDK1.4 之后出现的 NIO

    java连接mysql

    文章主要描述的是java连接MYSQL数据库的正确操作步骤,在此篇文章里我们主要是以实例列举的方式来引出其具体介绍。先创建数据库: CREATE DATABASE SCUTCS; 接着,创建表: CREATE TABLE STUDENT ( SNO CHAR(7)...

    K3标准凭证引入、引出

    金蝶K3凭证引入引出的指导,适合新手使用!欢迎大家下载

    由一桩盗窃案引出的话题.docx

    由一桩盗窃案引出的话题.docx

    引出端及整体安装件强

    GBT 2423.60-2008 电工电子产品环境试验 第2部分:试验方法 试验U:引出端及整体安装件强度.pdf

    java继承及多态概念PPT

    本PPT对java继承的基本概念,语法及应用进行了讲解。在继承的基础上进一步讲解了由继承引出的方法重写及上塑造性,最后引出多态的概念以及相关代码实例

    Beatles9527#StudyNotes#_21Java8语法新特性1

    参考《Java注解》第三章内容四. 接口默认方法——Java也会出现多继承问题Java8新特性default关键字,引出Java多继承问题五. Java8新特性

Global site tag (gtag.js) - Google Analytics