深入理解JVM二:垃圾收集器与内存分配策略

游戏安全逆向实战:如何用010Editor绕过ACE反作弊的文件校验(附详细步骤) 本文详细介绍了如何通过逆向工程思维和010Editor工具,针对PC游戏中ACE反作弊系统的文件校验机制进行分析与绕过。文章以实战案例为核心,逐步拆解了定位校验逻辑、解析校验数据文件、计算并替换哈希值的关键步骤,为安全研究人员提供了一种在用户态(Ring 3)层面进行轻量化对抗的思路与方法。 阅读详情

一、概述

垃圾收集器(Garbage Collection, GC), 大部分人把这项技术当做Java语言的伴生产物,实际上,GC的历史更加久远。
在Java语言中,线程隔离的三个区域内的内存分配和回收都具备确定性,不需要过多考虑回收的问题,因为会随着线程的结束而回收。Java堆和方法区则不一样,GC关注的也是这部分内存。

二、判断对象是否存活

2.1 引用计数法

给对象添加一个引用计数器,每当一个地方引用它,计数器数值加1;当引用失效时,计数器值就减1;计数器数值为0的对象就是不可能被使用的。实现简单,效率高(python使用)。主要缺点:很难解决对象之间互相循环引用的问题。

2.2 可达性分析算法

在主流的商用语言(java,C#)通过可达性分析来判定对象是否存活。通过 GCRoos对象作为起点,当一个对象到GC Roots没有任何引用链相连,则证明此对象不可用。
在Java语言中,可作为GC Roots的对象包括下面几种:

  • 虚拟机栈中引用的对象
  • 方法区中类静态属性引用的变量
  • 方法区中常量引用的对象
  • 本地方法栈中JNI(Native方法)引用的对象

2.3 引用的分类

这四种引用强度依次减弱

  • 强引用
    在程序代码中普遍存在的,类似Object obj = new Object(),只要强引用还在,GC永远不会回收掉被引用的对象。
  • 软引用
    描述一些还有用但并非必须的对象,对于软引用关联着的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收。SoftReference类
  • 弱引用
    描述非必须对象,比软引用更弱,被弱引用关联着的对象只能生存到下一次垃圾收集发生之前。WeakReference类
  • 虚引用
    也称为幽灵引用或者幻影引用,是最弱的一种引用关系。一个对象是否有虚引用的存在完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为对象设置虚引用的唯一目的是在被GC回收时能手打一个系统通知。PhantomReference类

2.4 生存还是死亡

至少经历两次标记过程,才会被回收
对象的finalize()方法只会被系统调用一次,下一次回收则不会执行

2.5 回收方法区

方法区(HotSpot虚拟机中的永久代)中的垃圾收集主要回收两部分内容:废弃常量和无用的类。回收废弃常量与Java堆中的对象非常类似。
而满足下面3个条件才能算是“无用的类”:

  • 该类的所有实例都已经被回收,也就是Java堆中不存在该类的任何实例
  • 加载该类的ClassLoader已经被回收
  • 该类对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射访问该类的方法

虚拟机可以对满足上述3个条件的无用类进行回收,并不必然。

三、垃圾收集算法

介绍几种算法的思想及发展过程

3.1 标记-清除算法

首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。
不足:

  • 效率问题,标记和清除的两个过程的效率都不太高
  • 空间问题,标记清除后会产生大量不连续的内存碎片,会导致当需要分配较大对象时,无法找到连续的内存而触发另一次垃圾收集动作。

3.2 复制算法

将内存分成大小相等的两块,每次只使用其中的一块,但这一块用完了,就将还存活的对象复制到另一块,然后将已使用的空间一次清掉。这样就解决了内存碎片的问题,但内存缩小了一半。
现在商用虚拟机,一般分 Eden和两个survivor(8:2)

3.3 标记-整理算法

过程与标记-清除一样,但后续不是直接对回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理边界以外的内存。

3.4 分代收集算法

当前商业虚拟机的垃圾收集都采用“分代收集”算法。根据对象存活周期的不同将内存划分为几块。一般把Java堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。

四、HotSpot的算法实现

这部分介绍如何发起内存回收

4.1 枚举根节点

可达性分析,会导致GC进行时会停顿所有Java线程。准确式GC,并不需要一个不漏检查所有引用位置,虚拟机有办法直接得知哪些地方存放着引用(OopMap)

4.2 安全点(Safepoint)

程序到达该点后,才会暂停开始GC

  • 抢先式中断
    现在几乎没有这种方式
  • 主动式中断
    设置标志,当需要暂停线程时,标志置位,线程执行到test(test指令是HotSpot生成的轮询指令)指令时就会触发中断

4.3 安全区域

安全点似乎已经完美地解决了如何进入GC的问题,但实际情况却不一定。在程序不执行的时候,系统没有为该线程分配CPU,典型的例子就是线程处于Sleep状态,这时候无法主动走到安全点去中断。
安全区域是指在一段代码片段中,引用关系不会发生变化。在这个区域中的任意地方开始GC都是安全的,可以看做是拓展了的安全点。
在线程执行到安全区域中的代码时,首先标识自己已经进入了安全区;当JVM开始GC的时候,就不用管这些线程了。当线程要离开安全区时,它要检查系统是否已经完成了根节点枚举(或者整个GC过程),如果没有完成,则需要等待完成之后,线程才可以安全离开安全区。

五、垃圾收集器

收集算法是内存回收的方法论,垃圾收集器就是内存回收的具体实现。Java虚拟机规范对垃圾收集器该如何实现并没有任何规定,因此不同的虚拟机的垃圾收集器可能会有很大差别。垃圾收集器没有最好的,只有最合适的。

5.1 Serial收集器

新生代 采取复制算法
最基本,发展历史最悠久的收集器。顾名思义,是一个单线程收集器,在进行垃圾收集时,会暂停所有工作线程(Stop The World)。HotSpot虚拟机开发团队为消除因垃圾回收导致的停顿而努力,开发出了很多垃圾收集器,时间的确在缩短,但没办法完全消除。
简单而高效,对于运行在Client模式下的虚拟机是一个很好的选择。

5.2 ParNew 收集器

新生代 复制算法
Serial收集器的多线程版本,它是除Serial之外,唯一能和CMS收集器配合工作的

5.3 Parallel Scanvenge收集器

新生代 复制算法,并行多线程。
该收集器的特点是以吞吐量(吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间))为目标

5.4 Serial Old 收集器

老年代 标记-整理算法
主要意义给Client模式下的虚拟机使用

  • 与Parallel Scanvenge搭配使用
  • 作为CMS收集器的后备预案

5.5 Parallel Old收集器

老年代 标记-整理算法,使用多线程
可以替代Serial Old 与Parallel Scanvenge搭配使用

5.6 CMS (Concurrent Mark Sweep)收集器

老年代 标记-清除
是一种以获取最短回收停顿时间为目标的收集器,应用在互联网站或者B/S系统的服务端上。
分为四个步骤:

  • 初始标记
    标记一下GC Roots能直接关联到的对象,速度快,需要停顿
  • 并发标记
    GC Roots Tracing,时间长,无需停顿
  • 重新标记
    修正并发标记期间用户程序产生的变动,需要停顿,比初始表记时间稍长
  • 并发清除
    无需停顿

是一款优秀的收集器,称之为并发低停顿收集器,但是有三个明显的缺点

  • CMS收集器对CPU资源非常敏感,会占据一定的CPU资源
  • 无法处理浮动垃圾(并行程序运行时产生的垃圾),会出现Concurrent Mode Failure而导致另一次Full GC的产生,也可以临时启动 Serial Old收集器来重新处理老年代垃圾的收集。
  • 基于标记清除的算法会导致空间碎片的产生

5.7 G1(Garbage-First)收集器

是当今收集器计数发展的最前沿成果之一。面向服务端,具有以下特点

  • 并行与并发
    充分利用多CPU的、多核环境的硬件优势,来缩短停顿时间
  • 分代收集
    可以不需要其他收集器配合而独立管理整个GC堆
  • 空间整合
    整体来看是基于 标记-整理的算法,局部来看是基于 复制算法,因此不会产生内存空间碎片
  • 可预测的停顿
    建立可预测停顿时间模型,让使用者明确在一个长度为M毫秒时间片段内,GC时间不超过N毫秒

虽然保留分代的概念,但是新生代和老年代不再是物理隔离的了。分为多个大小相等的独立区域(Region),用Remembered Set来存储新生代和老年代的相互引用,大致可分一下步骤

  • 初始标记
  • 并发标记
  • 最终标记
  • 筛选回收

六、内存分配与回收策略

自动内存管理归结为解决两个问题:给对象分配内存以及回收分配给对象的内存。
注:新生代GC(Minor GC) 频繁迅速
老年代GC(Major GC /Full GC):出现Major GC,一般伴随着Minor GC,慢10倍以上

  • 对象优先在Eden分配
  • 大对象直接进入老年代
  • 长期存活的对象将进入老年代
    虚拟机为每一个对象定义了一个年龄计数器,经历一次Minor GC仍存活年龄加1,当到一定程度(默认15)就会晋升老年代。
  • 动态对象年龄判定
    如果在Survivor空间中相同年龄所有对象大小总和大于Survivor空间的一般,年龄大于或等于该年龄的对象就可以直接进入老年代
  • 空间分配担保
    当出现大量对象在Minor GC仍然存活的时候就需要老年代分配担保。
    只要老年代的连续空间大于新生代对象总大小或者历次晋升的平均大小就会进行Minor GC,否则将进行Full GC
云原生之容器编排实践-在K8S集群中使用Registry2搭建私有镜像仓库 基于前面搭建的3节点 Kubernetes 集群,今天我们使用 Registry2 搭建私有镜像仓库,这在镜像安全性以及离线环境下运维等方面具有重要意义。作为测试环境,本次使用 Registry2 搭建了私有镜像仓库,实际生产环境建议使用 Harbor;创建了一个 local-storage 的 StorageClass ,并使用本地磁盘的方式创建使用 PV ,实际建议使用 NFS 。 阅读详情

相关推荐

USB PD快充功率监测仪:高精度嵌入式USB电压电流测量终端

USB供电已从数据接口演进为关键电源总线,尤其在PD快充场景下,工程师亟需对5V–20V宽压范围内的实时电压、电流及瞬时功率进行精准捕获。其底层原理依赖高共模抑制比的高边电流检测与分压采样+ADC数字化处理,结合LDO低噪声供电保障模拟链路精度。该类设备的技术价值在于以低成本实现协议无关的‘电气层可视化’,规避商用ASIC测试仪的黑盒局限,支撑PD充电验证、电源设计调试与教学实验等工程实践。本文介绍的开源USB表即基于N32G430 MCU与INA199电流检测芯片,覆盖USB-C输入/输出双通道监测,具备

weixin_42174098的博客 207

垃圾回收算法和 GC Roots 的对象

方法区中类静态属性引用的对。本地方法栈中 JNI 引用的对象。方法区中常量引用的对象。虚拟机栈中引用的对象。

go9898的专栏 613

【tips】在PyCharm中安装opencv图文版详细教程

pip如下图所示,左边的蓝色图标就是终端。点开终端后,键入命令,按下回车后就开始下载了。如果你更喜欢图形化操作,可以在 PyCharm 中直接安装:。点击右上角的 +按钮(添加包)。搜索或,点击。

zhousanguhe的博客 6740

垃圾回收机制

尽管虚拟机内存的动态分配与内存回收技术很成熟,可万一出现了这样那样的内存溢出问题,那么将难以定位错误的原因所在。 为了高效的回收,jvm将堆分为三个区域:1.新生代(Young Generation)2.老年代(Old Generation);3.永久代(Permanent Generation)(jdk1.8之前) 1 判断对象是否存活算法 1.1 引用计数算法 这种算法判断很简单,简单来说就是...

孟庆云的博客 817

EML 全面实践指南:把 SAP RAP 业务对象玩出工程化的稳定与优雅

本文面向掌握ABAP基础、正在实施RAP的开发者,深入讲解EML(Entity Manipulation Language)的核心用法。文章围绕READ ENTITIES、MODIFY ENTITIES、COMMIT ENTITIES三大语句,详细解析其语义、类型体系、事务机制及工程实践。重点内容包括:字段裁剪、派生类型、草稿控制、批量更新、事务缓冲与保存序列等关键技术点,并配合真实案例代码。旨在帮助开发者在SAP ABAP On-Premise和BTP环境中构建可维护、可演进的业务对象访问层,同时避免常见

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 323

SSE 传输过程中,丢失空格和回车符,怎么解决?

Server - Sent Events(SSE)即服务器发送事件,是 HTML5 中的一项 Web API,用于实现服务器向客户端浏览器推送实时数据的功能。

933

GC用的引用可达性分析算法中,哪些对象可作为GC Roots对象

先说一下可达性分析算法的思想:从一个被称为GC Roots的对象开始向下搜索,如果一个对象到GC Roots没有任何引用链相连时,则说明此对象不可用。 在java中可以作为GC Roots的对象有以下几种: 虚拟机栈中引用的对象、方法区类静态属性引用的对象、方法区常量池引用的对象、本地方法栈JNI引用的对象 虽然这些算法可以判定一个对象是否能被回收,但是当满足上述条件时,一个对象 不

ma345787383的博客 1万+

嵌入式面经篇八——进程&线程

记录一些招聘公司在招聘嵌入式软件岗位时的一些问题,此文为第八篇。进程上文:是指进程由用户态切换到内核态时需要保存用户态时CPU寄存器中的值,进程状态以及堆栈上的内容。即保存当前进程的状态,以便再次执行该进程时,能够恢复切换时的状态,继续执行。进程下文:是指切换到内核态后执行的程序,即进程运行在内核空间的部分。中断上文:硬件通过中断触发信号,导致内核调用中断处理程序,进入内核空间。这个过程中,硬件的一些变量和参数也要传递给内核,内核通过这些参数进行中断处理。

明天你好的博客 1854

可作为GC Root的对象

在Java虚拟机中判断一个对象是否可以被回收,有一种做法叫可达性分析算法,也就是从GC Root到各个对象,如果GC Root到某个对象还有可达的引用链,那么这个对象就还不能被回收,否则就等着被收割吧。这里既然提到了GC Root,那么哪类对象可以作为GC Root呢,这是一个在面试中经常被问到的问题。《深入理解Java虚拟机》一书中是这么说的,一下几种对象可以作为GC Root: 虚拟机栈中的引用

K.Sun 9235

YOLOv13改进策略【Neck篇】| GSConv 轻量卷积,Slim-Neck 减参数还不掉点

Neck 篇的第二篇继续"替换式"改进,这次的对象是 Neck 里的下采样卷积。GSConv 出自《Slim-neck by GSConv: a better design of lightweight detector》(2022),它的出发点:DWSConv(深度可分离)轻但"信息混不进通道",标准卷积重但表达好——GSConv 用GConv(分组卷积)混通道 + DWConv 补空间 + Channel Shuffle 打散,两全其美。

qq_53329130的博客 28

python批量调用大模型API:多线程和异步协程

本文介绍了利用多线程技术批量调用大模型API的实现方法。核心是通过并发请求提高处理效率,主要采用线程池管理并发数量、结果聚合等技术。文章提供了一个完整的Python实现示例,包含APIBatchCaller类及其single_api_call和batch_call方法,详细解析了并发控制、错误处理等关键点,并给出了使用注意事项,包括并发数设置、重试策略和超时处理等。该方案特别适合IO密集型任务,能显著提升批量API调用的效率。

Cachel Wood的博客 759

Parallel Scavenge收集器

Parallel Scavenge收集器what(是什么)Parallel Scavenge收集器是Java虚拟机中垃圾收集器的一种。 又称为吞吐量优先收集器,和ParNew收集器类似,是一个新生代收集器。使用复制算法的并行多线程收集器。 而且是并行的多多线程收集器.java1.8默认的收集器.why(为什么使用它)特点: Parallel Scavenge收集器的关注点与其他收集器不同,

kekeair的博客 5121

当几何失效时:3D激光SLAM退化场景的本质与应对策略

本文探讨了3D激光SLAM在退化场景(如长廊、隧道等)中的挑战与解决方案。文章从数学角度分析了退化原因,指出信息矩阵秩亏导致某些方向约束缺失。主流算法采用不同策略应对:LeGO-LOAM利用地面约束与解耦优化;LIO-SAM/LVI-SAM通过多传感器融合补偿;FAST-LIO系列依赖IMU短期积分。新兴的RID-LIO方案创新性地利用激光强度信息增强约束,实验显示精度提升63.59%。研究表明,针对不同退化方向需要采用特异性补偿策略,而挖掘现有传感器的潜在信息维度是提升鲁棒性的有效途径。

Studying…… 617

深入理解JVM读书笔记二: 垃圾收集器与内存分配策略

3.2对象已死吗? 3.2.1 引用计数法 给对象添加一个引用计数器,每当有一个地方引用它的地方,计数器值+1;当引用失效,计数器值就减1;任何时候计数器为0,对象就不可能再被引用了。 它很难解决对象之间相互循环引用的问题。 3.2.2 可达性分析算法 这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为...

勿忘初心 2202

深度学习工具包 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")

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

深入理解JVM读书笔记二:垃圾收集器与内存分配策略

一、判断对象死亡的两种常用算法:                在堆里面存放着java世界中几乎所有的实例对象,垃圾收集器在堆进行回收前,第一件事情就是要确定哪些对象还存活着,哪些已经死去。 1、引用计数算法 概念:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是不可能再被使用的。但是主流的java虚拟机并没有选...

qq_26891141的博客 337

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

深入理解JVM垃圾收集器与内存分配策略

在Java虚拟机中,“垃圾”指的是内存中不再使用或不可达的对象。垃圾收集器(GC)的主要任务就是识别并回收这些垃圾对象,释放内存资源。在JVM中,垃圾收集器管理的是堆(Heap)和方法区(Method Area)中的对象,它们的生命周期是动态的,需要在运行时进行分配和回收。JVM的垃圾收集机制通过多种垃圾收集算法和策略来优化内存回收,提升程序性能。理解不同垃圾收集器的特点及内存分配策略,能够帮助开发者更好地管理Java应用的内存,减少垃圾回收带来的性能损耗。

dm菜鸟编程的专栏 1213

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

深入理解Java虚拟机:Jvm总结-垃圾收集器与内存分配策略

但是会存在跨代引用的情况,即新生代中对象有可能被老年代所引用,实际情况中,存在互相引用的对象是偏向于同时存活或同时消亡的(被老年代引用的对象在收集时会存活下来然后晋升到老年代),根据第三个假说,为了避免检查跨代引用时扫描整个老年代,可以建立一个记忆集,把老年代划分成若干小块并标识出哪块存在跨代引用,在发生新生代收集时,只有包含跨代引用的块会被加入到GC Roots扫描。冒险:把Survivor无法容纳的对象直接送入老年代,前提是老年代有空间容纳这些对象,但不确定被容纳的对象其中有多少能在回收中存活下来。

Oceáno的博客 1821

《深入理解Java虚拟机》 垃圾收集器与内存分配策略

垃圾收集的重要性:垃圾收集(Garbage Collection, GC)是Java虚拟机自动内存管理的核心机制,可以自动回收不再使用的内存,避免内存泄漏和内存溢出问题。垃圾收集的目标:最小化停顿时间、最大化吞吐量、最小化内存占用。

vesqis的博客 570

如何查看JVM使用的是什么垃圾收集器

本文介绍了如何查看JVM使用的垃圾收集器。然后又通过代码验证了一下大对象的内存分配策略:了解了什么情况下大对象会直接进入老年代。

长路漫漫,以勤作车 3300

深入理解 JVM——垃圾收集器

程序计数器、虚拟机栈、本地方法栈3个区域随线程而生/灭,每一栈帧中分配多少内存基本是在类结构确定下来时就已知的,这几个区域的内存分配和回收都具备确定性,方法或线程结束后内存自然就随着回收了。 而Java堆和方法区显然是不确定的,只有运行期间,才能知道程序创建哪些对象,这部分内存的分配和回收是动态的。

weixin_52344200的博客 717

细说JVM(垃圾收集器与内存分配)

一、基础性的概念 1、Minor GC 和 Full GC 新生代GC(Minor GC):指发生在新生代的垃圾收集动作,因为Java对象大多都具备朝生夕灭的特性,所以Minor GC非常频繁,一般回收速度也比较快。 老年代GC(Major GC / Full GC):指发生在老年代的GC,出现了Major GC,经常会伴随至少一次的Minor GC(但非绝对的,在Parallel Scav...

啦啦啦的博客 511

[jjzhu学java]之深入理解JVM之垃圾收集器与内存分配策略

深入理解JVM之垃圾收集器与内存分配策略 如何判断对象已经消亡 引用计数算法 根搜索算法 深入理解JVM之垃圾收集器与内存分配策略 java中对象的创建需要的内存都是在java堆中申请的,所以垃圾收集的区域就是对java堆和方法区的内存区域进行GC。 如何判断对象已经消亡 垃圾收集器的主要任务就是找出已经“消亡”的对象,将其标记并清除其说用内存的过程,如何判断某个对象已

jjzhu_zju的博客 615

【深入理解JVM】垃圾收集器&内存分配策略

那么虚拟机要进行GC的时候,就不会管这些已经运行到安全区域的线程,当线程要脱离安全区域的时候,要自己检查系统是否已经完成了GC或者根节点枚举(这个跟GC的算法有关系),如果完成了就继续执行,如果未完成,它就必须等待收到可以安全离开安全区域的Safe Region的信号为止。简单解释一下,当线程1,线程2 是两个十分耗时的循环,并且根据HotSpot放置安全点的位置来说,上一段代码是典型的 counted loop(可数循环),也就是说每次循环回跳前是不会放置安全点的。所以这里就引入了安全点的概念。

fanday的博客 563

JVM之垃圾收集器与内存分配策略(二)

本篇文章是继JVM之垃圾收集器与内存分配策略(一)后写的,同样是笔者从《深入理解JVM虚拟机》中总结下来的,当做笔记。 GC类型以及导致Full GC的情况以及解决方法 GC类型包括: Minor GC:对新生代进行的GC; Major GC:对老年代进行的GC; Full GC:对整个堆进行的GC。 导致Full GC的情况包括: System.gc()方法的调用:建议JVM进行Fu...

博客 307

深入理解Java虚拟机-垃圾收集器与内存分配策略

内存分区:将堆划分为多个等大的Region(1MB~32MB),每个Region可属于Eden、Survivor、Old或Humongous(大对象区)并发标记(Concurrent Mark):遍历对象图,标记可达对象(与用户线程并发)适用场景:大内存(6GB以上)、多核CPU,需平衡吞吐量与延迟(如大数据平台)并发清除(Concurrent Sweep):回收垃圾对象(与用户线程并发)老年代(Parallel Old):多线程标记-整理算法。重新标记(Remark):修正并发标记期间的变化(STW)

m13299531475的博客 1050

JVM内存分配策略

本篇内容来自深入理解java虚拟机_JVM高级特性和最佳实践 JVM内存分配策略 java的内存自动管理可以总结为自动分配和自动回收内存。 对象内存的分配主要是在堆上分配内存,对象主要分配在新生代的Eden区上,如果启动了本地线程分配缓冲,将按线程有限分配在TLAB上。少数情况可以直接分配在老年代中。 TLAB技术:JVM在内存新生代Eden Space中开辟了一小块线程私有的区域,称作TLAB(...

lidongxiu0714 3114
上一篇: 深入理解JVM一:Java内存区域与内存溢出异常
下一篇: 深入理解JVM四:Java内存模式与线程
张小飘
博客等级 码龄11年 9粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值