理解Java垃圾回收机制

深入理解Java对象与垃圾回收机制 本篇博客深入探讨了Java中对象的创建、引用、作用域以及垃圾回收机制的工作原理。通过实例和图表分析,揭示了对象何时成为垃圾回收的候选者,以及finalize()方法的调用条件。此外,文章还介绍了Java语言的一些核心优势,包括面向对象、封装、平台独立性、健壮性、简单性以及安全性。 阅读详情

理解java垃圾回收机制有什么好处呢?作为一个软件工程师,满足自己的好奇心将是一个很好的理由,不过更重要的是,理解GC工作机制可以帮助你写出更好的Java应用程序。

这是我个人的主观观点,但我相信一个人精通了GC,往往会是一个更好的Java程序员。如果你对GC感兴趣,那就意味着你有一定大规模应用开发的经验。如果你已经仔细过考虑选择合适的GC算法,这意味着你完全理解你开发的应用程序的功能。当然,这可能不是一个优秀开发者共同标准。然而,很少有人会反对我说的:理解GC是成为一个伟大的Java开发人员的要求。

这是“成为一个Java GC专家”系列文章的第一部分。这次我将讲述GC简介,而在下一篇文章中,我将讨论分析GC状态和来自NHN的GC调优的例子。

本文的目的是用简单的方式向你介绍GC。我希望这篇文章被证明是非常有帮助的。事实上,我的同事已经发表了一些关于Java内部机制的大文章,它们已经在推特变得很流行。你可以去看看。

回到垃圾收集器,在学习GC前,你应该知道一个技术名词:这个词是“stop-the-world。“ 无论你选择哪种GC算法,Stop-the-world都会发生。Stop-the-world意味着JVM停止应用程序,而去进行垃圾回收。当stop-the-world发生时,除了进行垃圾回收的线程,其他所有线程都将停止运行。被中断的任务将在GC任务完成后恢复执行。GC调优往往意味着减少stop-the-world的时间。

分代垃圾收集

在Java代码中,Java语言没有显式的提供分配内存和删除内存的方法。一些开发人员将引用对象设置为null或者调用System.gc()来释放内存。将引用对象设置为null没有什么大问题,但是调用system.gc()方法会大大的影响系统性能,绝对不能这个干。(谢天谢地,我还没看到任何NHN开发者调用这个方法。)

在Java中,由于开发人员没有在代码中显式删除内存,所以垃圾收集器会去发现不需要(垃圾)的对象,然后删除它们,释放内存。这款垃圾收集器是基于以下两个假设而创建的。(称他们为前提条件更好,而不是假设。)

  • 绝大多数对象在短时间内变得不可达
  • 只有少量年老对象引用年轻对象.

这些假设被称为“弱代假说”。为了发挥这一假设的优势,在HotSpot虚拟机中,物理的将内存分为两个—年轻代(young generation)和老年代(old generation)。

年轻代:新创建的对象都存放在这里。因为大多数对象很快变得不可达,所以大多数对象在年轻代中创建,然后消失。当对象从这块内存区域消失时,我们说发生了一次“minor GC”。

老年代:没有变得不可达,存活下来的年轻代对象被复制到这里。这块内存区域一般大于年轻代。因为它更大的规模,GC发生的次数比在年轻代的少。对象从老年代消失时,我们说“major GC”(或“full GC”)发生了。

我们看一下这幅图。

图 1: GC区 & 数据流

上图中的永久代(permanent generation)也称为“方法区(method area)”,他存储class对象和字符串常量。所以这块内存区域绝对不是永久的存放从老年代存活下来的对象的。在这块内存中有可能发生垃圾回收。发生在这里垃圾回收也被称为major GC。

一些人可能想知道:

一个老年代的对象需要引用年轻代的对象,该怎么办?

为了解决这些问题,老年代中有一个被称为“卡表(card table)”的东西,它是一个512 byte大小的块。每当老年代的对象引用年轻代对象时,这种引用会被记录在这张表格中。当垃圾回收发生在年轻代时,只需对这张表进行搜索以确定是否需要进行垃圾回收,而不是检查老年代中的所有对象引用。这张表格用一个叫做“写闸(write barrier)”的东西进行管理。“写闸”是一种装置,对minor GC有更好性能。虽然因为这种机制,会产生一些时间性能开销,但降低了整体的GC时间。

图2: Card Table结构

年轻代组成部分

为了理解GC,我们学习一下年轻代,对象第一次创建发生在这块内存区域。年轻代分为3块。

  • Eden区
  • 2个Survivor区

年轻代总共有3块空间,其中2块为Survivor区。各个空间的执行顺序如下:

  1. 绝大多数新创建的对象分配在Eden区。
  2. 在Eden区发生一次GC后,存活的对象移到其中一个Survivor区。
  3. 在Eden区发生一次GC后,对象是存放到Survivor区,这个Survivor区已经存在其他存活的对象。
  4. 一旦一个Survivor区已满,存活的对象移动到另外一个Survivor区。然后之前那个空间已满Survivor区将置为空,没有任何数据。
  5. 经过重复多次这样的步骤后依旧存活的对象将被移到老年代。

通过检查这些步骤,如你看到的样子,其中一个Survivor区必须保持空。如果数据存在于两个Survivor区,或两个都没使用,你可以将这个情况作为系统错误的一个标志。

经过多次minor GC,数据被转移到老年代过程如下面的图表所示:

图3: GC前和GC后

请注意,在HotSpot虚拟机中,使用两种技术加快内存的分配。一个被称为“指针碰撞(bump-the-pointer)”,另外一个被称为“TLABs(线程本地分配缓冲)”。

指针碰撞技术跟踪分配给Eden区上最新的对象。该对象将位于Eden 区的顶部。如果之后有一个对象被创建,只需检查Eden区是否有足够大的空间存放该对象。如果空间够用,它将被放置在Eden区,存放在空间的顶部。因此,在创建新对象时,只需检查最后被添加对象,看是否还有更多的内存空间允许分配。然而,如果考虑多线程的环境,则是另外一种情况。为了实现多线程环境下,在Eden 区线程安全的去创建保存对象,那么必须加锁,因此性能会下降。在HotSpot虚拟机中TLABs能够解决这一问题。它允许每个线程在Eden区有自己的一小块私有空间。因为每一个线程只能访问自己的TLAB,所以在这个区域甚至可以使用无锁的指针碰撞技术进行内存分配。

我们已经对年轻代有了一个快速的浏览。你不需要要记住我刚才提到的两种技术。即便你不知道他们,也不会怎么样。但请务必记住:对象第一次被创建发生在Eden区,长期存活的对象被移动到老年代的Survivor区。

老年代GC

当老年代数据满时,基本上会执行一次GC。执行程序根据不同GC类型而变化,所以如果你知道不同类型的垃圾收集器,会更容易理解垃圾回收过程。

在JDK7中,有5种垃圾收集器:

  1. Serial收集器
  2. Parallel收集器
  3. Parallel Old收集器 (Parallel Compacting GC)收集器
  4. Concurrent Mark & Sweep GC  (or “CMS”)收集器
  5. Garbage First (G1) 收集器

其中,serial 收集器一定不能用于服务器端。这个收集器类型仅应用于单核CPU桌面电脑。使用serial收集器会显着降低应用程序的性能。

现在让我们来了解每个收集器类型。

Serial 收集器 (-XX:+UseSerialGC)

我们在前一段的解释了在年轻代发生的垃圾回收算法类型。在老年代的GC使用算法被称为“标记-清除-整理”。

  1. 该算法的第一步是在老年代标记存活的对象。
  2. 从头开始检查堆内存空间,并且只留下依然幸存的对象(清除)。
  3. 最后一步,从头开始,顺序地填满堆内存空间,将存活的对象连续存放在一起,这样堆分成两部分:一边有存放的对象,一边没有对象(整理)。

serial收集器应用于小的存储器和少量的CPU。

 

Parallel收集器(-XX:+UseParallelGC)

图4: Serial收集器 和 Parallel收集器的差异 

从这幅图中,你可以很容易看到Serial收集器 和 Parallel收集器的差异。serial收集器只使用一个线程来处理的GC,而parallel收集器使用多线程并行处理GC,因此更快。当有足够大的内存和大量芯数时,parallel收集器是有用的。它也被称为“吞吐量优先垃圾收集器。”

Parallel Old 垃圾收集器(-XX:+UseParallelOldGC)

Parallel Old收集器是自JDK 5开始支持的。相比于parallel收集器,他们的唯一区别就是在老年代所执行的GC算法的不同。它执行三个步骤:标记-汇总-压缩(mark – summary – compaction)。汇总步骤与清理的不同之处在于,其将依然幸存的对象分发到GC预先处理好的不同区域,算法相对清理来说略微复杂一点。

CMS GC (-XX:+UseConcMarkSweepGC)

图5: Serial GC & CMS GC

 

CMS垃圾收集器(-XX:+UseConcMarkSweepGC)

如你在上图看到的那样, CMS垃圾收集器比之前我解释的各种算法都要复杂很多。初始标记(initial mark) 比较简单。这一步骤只是查找距离类加载器最近的幸存对象。所以停顿时间非常短。之后的并发标记步骤,所有被幸存对象引用的对象会被确认是否已经被追踪检查。这一步的不同之处在于,在标记的过程中,其他的线程依然在执行。在重新标记步骤会修正那些在并发标记步骤中,因新增或者删除对象而导致变动的那部分标记记录。最后,在并发清除步骤,垃圾收集器执行。垃圾收集器进行垃圾收集时,其他线程的依旧在工作。一旦采取了这种GC类型,由于垃圾回收导致的停顿时间会极其短暂。CMS 收集器也被称为低延迟垃圾收集器。它经常被用在那些对于响应时间要求十分苛刻的应用上。

当然,这种GC类型在拥有stop-the-world时间很短的优点的同时,也有如下缺点:

  •  它会比其他GC类型占用更多的内存和CPU
  •  默认情况下不支持压缩步骤

在使用这个GC类型之前你需要慎重考虑。如果因为内存碎片过多而导致压缩任务不得不执行,那么stop-the-world的时间要比其他任何GC类型都长,你需要考虑压缩任务的发生频率以及执行时间。

G1 GC

最后,我们来学习一下G1类型。

图6: Layout of G1 GC

如果你想要理解G1收集器,首先你要忘记你所理解的新生代和老年代。正如你在上图所看到的,每个对象被分配到不同的网格中,随后执行垃圾回收。当一个区域填满之后,对象被转移到另一个区域,并再执行一次垃圾回收。在这种垃圾回收算法中,不再有从新生代移动到老年代的三部曲。这个类型的垃圾收集算法是为了替代CMS 收集器而被创建的,因为CMS 收集器在长时间持续运行时会产生很多问题。

G1最大的好处是他的性能,他比我们在上面讨论过的任何一种GC都要快。但是在JDK 6中,他还只是一个早期试用版本。在JDK7之后才由官方正式发布。就我个人看来,NHN在将JDK 7正式投入商用之前需要很长的一段测试期(至少一年)。因此你可能需要再等一段时间。并且,我也听过几次使用了JDK 6中的G1而导致Java虚拟机宕机的事件。请耐心的等待它更稳定吧。

下一次我将讨论GC优化相关问题,但是在此之前我要先明确一件事情。假如应用中创建的所有对象的大小和类型都是统一的,在我们公司,这种情下使用的WAS的GC参数 可以是相同的。但是WAS所创建对象的大小和生命周期根据服务以及硬件的不同而不同。换句话说,不能因为某个应用使用的GC参数“A”,就说明同样的参数 也能给其他服务带来最佳效果。而是要因地制宜,有的放矢。我们需要找到适合每个WAS线程的最佳参数,并且持续的监控和优化每个设备上的WAS实例。这并不是我的一家之谈,而是负责Oracle Java虚拟机研发的工程师在 JavaOne 2010上已经讨论过的。

本文中我们简略的介绍了Java的垃圾回收机制,请继续关注我们的后续文章,我们将会讨论如何监控Java GC状态以及GC调优。

另外,我特别推荐一本2011年12月发布的《Java性能》(Amazon,也可以通过safari在线阅读),还有在Oracle官网发布的白皮书《Java HotSpotTM虚拟机内存管理》(这本书与Java性能优化不是同一本)

作者Sangmin Lee, NHN公司,性能设计实验室高级工程师。

可参考:http://blog.jobbole.com/80499/


ESP32 STA AP模式下,设备连接 ESP的AP 后无法上网,无法访问域名上网(或者Failed to enable NAPT) ESP32 STA AP模式下,设备连接 ESP的AP 后无法上网,无法访问域名上网(或者Failed to enable NAPT)1.可能是ESP STA模式未成功连接到路由器,确保 STA 成功连接到外部网络。2.检查 STA 和 AP 的网络配置是否正确,避免子网冲突。3.ESP32的NAPT功能未正确启用,确保 menuconfig 中已启用 IP_NAPT。4.DNS服务器未正确配置。 阅读详情

相关推荐

CASIA数据集解析:图像篡改检测的黄金标准与实践指南

本文深入解析了CASIA数据集在图像篡改检测领域的核心价值与应用实践。作为中科院自动化所打造的黄金标准,CASIA数据集通过模拟真实篡改场景(如拼接和复制移动)为研究者提供全面支持。文章详细对比了v1.0与v2.0版本差异,分享数据预处理和模型训练的最佳实践,并探讨了未来研究方向,是图像篡改检测领域的重要参考指南。

kappa的博客 783

jvm常用配置

java -Xmx3800m -Xms3800m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:SurvivorRatio -XX:NewRation -XX:MaxTenuringThreshold -XX:+UseParallelGC :选择垃圾收集器为并行收集器。 此配置仅对年轻代有效。即上述配置...

mojolang 800

window下安装并使用nvm(含卸载node、卸载nvm、全局安装npm)

文章目录一、卸载node二、安装nvm三、配置路径和下载源四、使用nvm安装node五、nvm常用命令六、卸载nvm七、遇到的问题 nvm 全名 node.js version management,顾名思义是一个nodejs的版本管理工具。通过它可以安装和切换不同版本的nodejs。 一、卸载node 如果你已经安装了node,那么你需要先卸载node,如果你没有安装那直接跳过这一步到下一步。 打开控制面板 -> 打开程序和功能 -> 右上角搜索输入node -> 右键卸载 为了确保彻底

HuangsTing的博客 41万+

GC参数

1.串行收集器: 1,最古老,最稳定 2,效率高 3,可能会产生较长的停顿       -XX:+UseSerialGC          --新生代,年老代使用串行回收             --新生代复制算法             --年老代标记-压缩     应用程序线程可能有多个,一旦回收开始,这些线程全部暂停,由GC线程接替运行,在串行回收器中,gc线程只有一个,

天空之城 857

SAP CO实战:如何用KKA2/CJ88结果分析码搞定项目收入成本匹配(附真实案例)

本文深入探讨了SAP CO模块中KKA2和CJ88结果分析码在项目收入成本匹配中的高阶应用。通过真实案例解析,详细介绍了这两种分析码在分阶段收入确认和终验法项目中的配置技巧与实战经验,帮助财务人员高效解决复杂业务场景下的财务数据处理难题。

weixin_29230773的博客 166

华为防火墙 策略路由实现多ISP接入Internet

PC3上网访问Server1时走ISP1。PC4上网访问Server1时走ISP2。1、配置接口IP并加入相应的安全区域。二、ISP2 运营商 R2路由器。一、ISP1 运营商 R1路由器。

一直被模仿,从未被超越 3013

Parallel垃圾回收器总结

一、概述 HotSpot的年轻代中除了拥有ParNew收集器是基于并行回收的以外,Parallel Scavenge收集器同样也采用了复制算法、并行回收和"Stop the World"机制。 那么Parallel 收集器的出现是否多此一举? 和ParNew收集器不同,Parallel Scavenge收集器的目标则是达到一个可控制的吞吐量,它也被称为吞吐量优先的垃圾收集器。 自适应调节策略也是Parallel Scavenge与ParNew一个重要区别。 高吞吐量则可以高效率地利用CPU时间,尽快

weixiaohuai的博客 3419

Pdu Router(PduR)模块

1. PduR路由基本功能 2. PduR总线网关功能 3. PduR缓存机制 4. 总结

weixin_43759043的博客 3849

Java面试之JVM

194. 说一下 JVM 的主要组成部分?及其作用? 类加载器(ClassLoader) 运行时数据区(Runtime Data Area) 执行引擎(Execution Engine) 本地库接口(Native Interface) 组件的作用: 首先通过类加载器(ClassLoader)会把 Java 代码转换成字节码,运行时数据区(Runtime Data Area)再把字节码加载到内...

jushisi的博客 255

数学建模学习(120):使用Python实现基于AHP的供应商选择分析

使用Python实现基于AHP的供应商选择分析

全栈川川 909

SAP物料主数据中的销售视图。这是一个在销售与分销模块中至关重要的核心主数据,直接关系到从报价到交货的整个销售流程

SAP物料主数据的销售视图是销售流程的核心基础,它定义了物料如何被销售、定价、开票和交付。销售视图包含五个关键控制点:1)基本销售数据控制物料销售状态;2)销售组织数据决定销售渠道和产品分类;3)通用物料数据管理销售描述和税务分类;4)交货计划控制交付参数;5)开票计划管理定价规则。这些设置直接影响销售流程顺畅度、数据准确性、客户满意度、财务合规性和业务灵活性。建议将销售视图创建纳入新产品引入流程,并建立规范的维护机制,确保业务变化时及时更新配置。

金牌架构师 666

JVM学习笔记_垃圾收集器重要参数

目录-XX:+UseParallelGC-XX:+UseSerialGC-XX:+UseParNewGC-XX:+UseConcMarkSweepGC-XX:PretenureSizeThreshold-XX:MaxTenuringThreshold-XX:TargetSurvivorRatio 垃圾收集器有串行收集器,比如 Serial收集器+Serial Old收集器,Parallel Scavenge+Parallel Old收集器等等。该如何让这些不同的垃圾收集器组合触发使用呢? -XX:+UseP

dcj199411的专栏 3052

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Java垃圾回收机制深入理解

Java垃圾回收机制是Java虚拟机(JVM)的核心组件之一,对于内存管理起到至关重要的作用。它能自动追踪并管理应用程序中创建的对象,当这些对象不再使用时,垃圾回收机制会自动回收其占用的内存,使这部分内存能够被再次利用。此机制极大地减少了开发者需要手动管理内存的负担,防止了因为疏忽导致的内存泄漏问题,是Java语言相较于C++等其他语言的一个显著优点。在Java中,对象的生命周期从创建(new)开始,到不再被其他对象引用结束。

沐雨风栉 4460

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

理解 Java 垃圾回收机制

理解java垃圾回收机制有什么好处呢?作为一个软件工程师,满足自己的好奇心将是一个很好的理由,不过更重要的是,理解GC工作机制可以帮助你写出更好的Java应用程序。 这是我个人的主观观点,但我相信一个人精通了GC,往往会是一个更好的Java程序员。如果你对GC感兴趣,那就意味着你有一定大规模应用开发的经验。如果你已经仔细过考虑选择合适的GC算法,这意味着你完全理解你开发...

a752392的博客 134

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

深入理解java垃圾回收机制

一:垃圾回收机制的意义 java 语言中一个显著的特点就是引入了java回收机制,是c++程序员最头疼的内存管理的问题迎刃...

5437

深入理解Java垃圾回收机制

深入理解Java垃圾回收机制

fjjjyf的博客 256

深入理解Java中的垃圾回收机制

在Java中,垃圾回收(Garbage Collection,简称GC)是一个非常重要的机制,它能够自动管理内存,释放不再使用的对象,避免内存泄漏。通过本文的介绍,我们深入理解了Java中的垃圾回收机制,包括垃圾回收的基本概念、垃圾回收算法、垃圾回收器、垃圾回收的工作过程以及如何优化垃圾回收。垃圾回收是Java语言的重要特性之一,它能够自动管理内存,简化编程的复杂性,提高程序的性能和稳定性。在Java中,垃圾回收由Java虚拟机(JVM)自动执行,程序员不需要手动管理内存,这大大简化了内存管理的复杂性。

聚娃科技开发者博客 633

Java垃圾回收机制的理解

Java与C++有一个很大的不同点就是使用Java编程时我们不用特意关注内存的使用,尤其是内存的释放。在C++中,用new关键字申请的内存区域得不到delete关键字的清理时就会产生内存泄漏问题,在Java中,jvm有自己的垃圾回收机制,能自动的回收我们不会再使用的对象。 判别垃圾算法 1.引用计数法 在Java中我们new一个对象时会得到一个这个对象类型的引用。 例如 String st...

yan245294305的博客 968

深入理解Java的垃圾回收机制

  1.当一个对象不再被程序所引用时,它所使用的堆空间可以被回收,以便被后续的新对象使用;  2.GC需要实现的功能   (1)判断哪些对象不再被程序所引用   (2)释放无用对象的内存   (3)执行无用对象的终结方法   (4)移动活动对象在堆中的位置,减少堆内存中的碎片《因为对象在堆中的内存不是连续分配的,因此可能的情况是,需要为一个新的对象分配内存空间时,堆中的剩余空间足够为新对象分配内存,但是因为这些空闲的区域不连续,导致需要扩大堆的内存空间》  3.使用GC的好处   (1)提高程序员的编程效率

JBuilder3的专栏 1243

Java垃圾回收机制理解

垃圾回收机制的理解。

daguairen的博客 1万+

java垃圾回收机制的理解

关于java垃圾回收的理解,即gc,来源于 java编程思想 一书 垃圾回收的算法 引用计数法 引用计数法是一种简单但是速度很慢的回收计数,每个 对象都含有一个引用计数器,当有引用连接至对象时,引用计数器加一,当引用离开作用域或对象被置为null时,引用计数器减一,虽然引用计数器的开销不大,但是这个开销在正好程序的生命周期都存在,垃圾回收器会遍历全部的对象,发现某个对象的引用计数器为零时,就释放它占用的内存。但是这种方法存在缺陷,如果对象存在交叉循环引用,那么计数器永远不为0,就可能出现对象应该被回收,

qq_35015497的博客 247

深入理解 Java 垃圾回收机制

https://zhuanlan.zhihu.com/p/76698728

qq_32067151的博客 137
上一篇: Java-JVM的内存调优
下一篇: 2016年5月热门IT职位的推荐
NextX工作室
博客等级 码龄18年 21粉丝 21原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值