容器内存黑洞排查手册:当PageCache让你的Pod莫名被OOM时

实战避坑指南:当K8s的JVM应用吃掉14G内存却显示空闲?-Xmx参数隐藏陷阱解析 本文深入解析了在Kubernetes环境中运行JVM应用时,因`-Xmx`参数配置不当导致容器内存使用率虚高的常见陷阱。文章通过对比容器与JVM的内存监控视角差异,揭示了G1GC等垃圾收集器的内存预分配与延迟释放机制是问题根源,并提供了从排查定位到精准计算内存配置的完整实战优化方案,帮助开发者有效规避资源浪费与Pod驱逐风险。 阅读详情

容器内存黑洞:当PageCache悄然吞噬你的Pod内存时

你是否曾在监控面板上看到容器的内存使用率远低于限制,但Pod却突然被OOM Killer无情终结?这种“内存充足却被OOM”的悖论,往往让开发者陷入困惑。问题的根源,通常隐藏在Linux内核的PageCache机制与容器内存统计的微妙差异之中。

在容器化环境中,内存管理远比表面看起来复杂。传统的top命令、docker stats输出,甚至kubectl top显示的数据,都可能给你带来误导性的安全感。真正决定容器生死的,是Kubernetes调度器关注的Working Set指标,而这个指标的计算方式,让PageCache成为了一个潜在的“内存黑洞”。

这篇文章将带你深入理解容器内存监控的真相,通过实际案例演示如何定位PageCache导致的内存问题,并提供从诊断到优化的完整解决方案。无论你是运维工程师还是应用开发者,掌握这些知识都能帮助你在生产环境中避免那些令人头疼的OOM事件。

1. 理解容器内存统计:Working Set与PageCache的微妙关系

要解开“内存充足却被OOM”的谜团,首先需要理解容器环境中几个关键的内存指标及其计算方式。在Linux cgroup内存子系统中,/sys/fs/cgroup/memory/目录下的文件记录了详细的内存使用情况,但这些原始数据需要正确解读。

1.1 核心内存指标解析

让我们先看看cgroup内存统计中的几个关键字段:

# 查看容器cgroup内存统计
cat /sys/fs/cgroup/memory/memory.stat

cache 1228800
rss 524288000
mapped_file 409600
inactive_file 819200
active_file 409600
total_inactive_file 819200
total_active_file 409600

这些指标的含义如下:

  • cache: PageCache的总大小,包括活跃和非活跃的文件缓存
  • rss: 常驻内存集,进程实际使用的物理内存(不含PageCache)
  • inactive_file: 非活跃文件缓存,可以被内核回收的内存
  • active_file: 活跃文件缓存,正在被频繁访问的缓存

注意:memory.usage_in_bytes显示的是容器cgroup内所有进程使用的总内存,它等于rss + cache + 其他内核内存。这个值通常比实际应用占用的内存要大,因为它包含了可以被回收的PageCache。

1.2 Working Set的计算逻辑

Kubernetes通过cadvisor获取容器内存使用情况,而cadvisor计算Working Set的算法决定了哪些内存被计入“实际使用”。查看cadvisor源码中的关键逻辑:

// cadvisor中WorkingSet的计算逻辑
workingSet := ret.Memory.Usage
if v, ok := s.MemoryStats.Stats["total_inactive_file"]; ok {
    if workingSet < v {
        workingSet = 0
    } else {
        workingSet -= v
    }
}
ret.Memory.WorkingSet = workingSet

这个计算可以简化为公式:

WorkingSet = memory.usage_in_bytes - total_inactive_file
          = (rss + cache + 其他内核内存) - inactive_file
          = rss + active_file + 其他内核内存

关键洞察:Working Set排除了inactive_file(非活跃文件缓存),但包含了active_file(活跃文件缓存)。这意味着频繁访问的文件缓存会被计入容器的“实际内存使用”,直接影响OOM判断。

1.3 不同工具的内存统计差异

理解不同监控工具的计算方式差异至关重要:

工具/命令 计算方式 包含PageCache 用于OOM判断
docker stats usage_in_bytes - cache 否 否
kubectl top usage_in_bytes - inactive_file 部分(仅active_file) 是
top命令(容器内) 仅进程RSS 否 否
cgroup memory.usage_in_bytes rss + cache + 内核内存 全部 否

这种差异解释了为什么容器内执行top显示内存使用率很低,但Pod却被OOM Killer终止。top只显示进程RSS,而Kubernetes的OOM决策基于Working Set,后者包含了活跃的PageCache。

2. PageCache如何成为内存黑洞:典型场景分析

PageCache的设计初衷是提升I/O性能,通过将频繁访问的文件数据缓存在内存中,减少磁盘访问。但在容器环境中,这种优化可能适得其反,特别是在以下场景中。

2.1 Java日志组件的“隐形”内存消耗

Java应用是PageCache问题的重灾区,尤其是使用Logback或Log4j2等日志框架时。考虑以下常见的Logback配置:

<appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>/app/logs/myapp.log</file>
    <append>true</append>
    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss} - %msg%n</pattern>
    </encoder>
</appender>

这种配置看起来无害,但实际上存在严重问题。FileAppender默认使用缓冲I/O,日志数据不会立即写入磁盘,而是先进入PageCache。在高日志量场景下,这可能导致数百MB甚至GB级别的PageCache积累。

更糟糕的是,当使用mmap进行文件操作时(NIO的MappedByteBuffer),情况会更加复杂:

// 使用MappedByteBuffer进行高效文件操作
MappedByteBuffer buffer = new RandomAccessFile("/app/data/large.bin", "rw")
    .getChannel()
    .map(FileChannel.MapMode.READ_WRITE, 0, 1024 * 1024 * 100); // 映射100MB文件

mmap将文件直接映射到进程地址空间,相关内存会计入mapped_file,这部分内存同样会被计入Working Set。当应用频繁读写大文件时,active_file会迅速增长,直接推高Working Set。

2.2 文件读取操作的内存陷阱

另一个常见场景是应用需要读取配置文件、模板文件或静态资源。考虑这个简单的Spring Boot应用代码:

@RestController
public class FileController {
    
    @GetMapping("/template/{name}")
    public String getTemplate(@PathVariable String name) {
        // 每次请求都读取文件
        return Files.readString(Path.of("/app/templates/" + name + ".html"));
    }
    
    @GetMapping("/report/{id}")
    public byte[] generateReport(@PathVariable String id) {
        // 读取大型报表文件
        return Files.readAllBytes(Path.of("/app/reports/report_" + id + ".pdf"));
    }
}

每次请求都会导致文件被读入PageCache。如果文件较大或请求频繁,active_file会持续增长。更隐蔽的是,即使应用已经处理完数据,只要文件描述符保持打开状态或文件被频繁访问,这些缓存就不会被释放。

2.3 共享PageCache的误解与真相

一个常见的误解是:多个Pod读取同一个文件会共享PageCache,从而减少总体内存占用。实际情况要复杂得多。

# 实验:两个Pod读取同一个大文件
# Pod A读取文件
kubectl exec pod-a -- dd if=/shared/data.bin of=/dev/null bs=1M

# Pod B读取相同文件
kubectl exec pod-b -- dd if=/shared/data.bin of=/dev/null bs=1M

# 检查各自的内存统计
kubectl exec pod-a -- cat /sys/fs/cgroup/memory/memory.stat | grep -E "cache|inactive_file|active_file"
kubectl exec pod-b -- cat /sys/fs/cgroup/memory/memory.stat | grep -E "cache|inactive_file|active_file"

你会发现:第一个读取文件的Pod会承担所有PageCache内存,后续Pod读取相同文件时,虽然命中系统级缓存(减少磁盘I/O),但不会在自己的cgroup中新增cache统计。这意味着:

  1. PageCache在系统层面是共享的
  2. 但内存统计只计入第一个访问者的cgroup
  3. 如果第一个Pod被删除,PageCache可能被保留在系统缓存中,但不属于任何容器

这种机制可能导致不公平的内存分配:一个“热心”的Pod为所有兄弟Pod缓存了数据,却独自承担内存成本,最终可能因为Working Set过高而被OOM。

3. 实战诊断:定位PageCache内存问题的工具与方法

当怀疑PageCache导致内存问题时,需要系统性的诊断方法。以下是基于实际经验的排查流程。

3.1 使用SysOM进行深度内存分析

阿里云的SysOM(System Observer Monitoring)提供了容器级别的详细内存分析能力。如果你使用的是阿里云ACK,可以直接启用此功能。对于其他环境,我们可以通过命令行工具实现类似的分析。

首先,检查容器的详细内存组成:

# 进入容器所在节点的cgroup目录
cd /sys/fs/cgroup/memory/kubepods.slice/
find . -name "*.scope" -type d | xargs -I {} sh -c 'echo "=== {} ===" && cat {}/memory.stat 2>/dev/null | grep -E "^(total_)?(cache|rss|active_file|inactive_file)"'

# 或者使用更友好的脚本格式
ca
Linux内存从0到1学习笔记(9.4,内存优化调试之使用page_owner分析内存黑洞) PageOwner用于跟踪每个内存页被谁分配走了。它可以用来分析内存泄漏,找出内存占用者后者。当分配内存时,分配的调用栈信息和内存页顺序会为每个内存页保存下来。当我们需要了解所有内存页的状态时,我们可以读取这些节点信息来分析内存分配的详细细节。 阅读详情

相关推荐

内存泄漏系列专题分析之二十三:meminfo无法统计到的黑洞内存泄漏分析

内存泄漏系列专题分析之二十三:meminfo无法统计到的黑洞内存泄漏分析

678

如何观察C#托管堆内存的“黑洞现象“

当我们的应用程序在运行过程中使用大量的内存时,有时会遇到所谓的"黑洞现象",即内存使用量急剧增加,但无法通过常规手段释放。在PerfView的"Memory"窗口中,我们可以点击"StackTrace"按钮,查看与内存分配和释放相关的堆栈跟踪信息。在PerfView的主界面上,点击"Collect"选项卡,然后选择"CPU Sampling"。使用PerfView工具可以帮助我们观察和分析这种"黑洞现象",并找到导致问题的代码。选择最新生成的文件,然后点击"View"选项卡,选择"Memory"。

library_git106的博客 188

从1MB到1TB:Elasticsearch内存黑洞如何“吃掉”你的服务器?

本文详细解析了Elasticsearch内存管理的关键策略。主要内容包括:1)通过JVM配置限制堆内存;2)识别Fielddata导致的"内存黑洞",建议改用keyword类型;3)优化查询缓存和分片配置;4)提供Java API和shell监控脚本。文章通过真实案例对比显示,优化后内存使用率可降低52.6%,Fielddata内存减少90%,节点崩溃率降为0。最后给出完整的"内存瘦身"流程图,帮助开发者实现ES集群的高效内存管理。

墨夶的博客 1580

[实践篇]13.9 如何使用gcore(ramdump)排查内存黑洞?

通常情况下我们使用dumpsys meminfo,还是procrank都可以找出内存占用失控的进程。当系统发生oom_panic时,我们同样有很多种手段来分析内存布局,如前面所说的memory.txt信息;但是极少数情况下我们会发现内存布局很平滑,各个进程并没有“偷吃”。但是同样可用内存以所剩无几,有可能是ion占用高,又或者是某个内核线程内存泄漏。且oom_killer或激进的lmk查杀策略都无法满足内存回收的需求,那么此时则需要分析ramdump中的page_tracking信息。

从0到1,突破自己 1891

海思ISP调优实战:从实验室到真实场景的IPC相机图像质量优化指南

本文深入探讨海思ISP调优在IPC相机图像质量优化中的实战应用,从实验室标定到真实场景部署的全链路调优方法。重点解决光照动态范围、色温变化和噪声特性等核心问题,提供AE权重表配置、CCM标定、3DNR时域滤波等关键技术方案,帮助实现从理论到实践的图像质量提升。

s3t4u的博客 745

飞书+扣子+DeepSeek三件套:5分钟搞定公众号文章批量改写(附完整配置截图)

本文详细介绍了如何利用飞书、扣子和DeepSeek三款工具,无需编程即可搭建一个高效的公众号文章批量改写自动化工作流。通过飞书多维表格管理链接与成果,扣子平台串联整个流程,并调用DeepSeek智能体进行内容润色与改写,实现从内容抓取到智能处理的完整自动化,大幅提升新媒体运营效率。

python9snake的博客 199

自动驾驶仿真(五)—— 基于Carsim、Prescan、Simulink的联合仿真

自动驾驶仿真五——基于Carsim、Prescan、Simulink的联合仿真1. 联合仿真流程2. CarSim联合仿真配置要点3. Prescan联合仿真配置要点4. Carsim、Prescan、Simulink联合仿真结果5. 参考学习的书目教材 博主前面的博文已经介绍了Carsim和Prescan各自与Matlab/Simulink的相关联合仿真应用实例,并且论述过几款软件各自的优势及用法,CarSim适合动力学模型的建立,PreScan适合行车场景的搭建,Simulink适合控制算法的设计及信号

zhudj08的博客 1万+

1、动作捕捉技术:概述与历史

本博文全面介绍了动作捕捉技术的概念、历史演变、类型分类以及完整的工作流程。从早期的连续摄影技术到现代数字动作捕捉系统,文章深入探讨了光学、磁性和机械动作捕捉系统的优缺点及适用场景,并详细解析了动作捕捉数据的生成原理与数学基础。此外,还涵盖了特殊部位如手部、面部和木偶的动作捕捉方法,并讨论了动作捕捉在动画制作、虚拟现实、医疗康复等领域的广泛应用与发展前景。

apple5的专栏 213

基于Dijkstra算法的共享单车调度优化系统设计与实现

根据最新统计数据,全球共享单车市场规模已超过300亿美元,中国作为最大的共享单车市场,日订单量超过5000万次。Dijkstra算法由荷兰计算机科学家Edsger W. Dijkstra于1956年提出,用于解决带权有向图中的单源最短路径问题。本文详细介绍了基于Dijkstra算法的共享单车调度优化系统的设计与实现。本文将详细介绍基于Dijkstra算法的共享单车调度优化系统的设计与实现,采用Java 17、Spring Boot 3.x等最新技术栈。

2201_76125393的博客 613

SOI LDMOS器件的Sentaurus TCAD建模与关键电学特性仿真研究

本文研究了SOI LDMOS器件的TCAD建模与电学特性仿真。通过Sentaurus TCAD平台建立了单RESURF结构的SOI LDMOS模型,详细阐述了器件结构原理和RESURF耐压机制。研究采用SDE进行几何定义和掺杂配置,在Sentaurus Device中构建了完整的物理模型体系,包括迁移率、复合和碰撞电离模型。通过系统仿真提取了器件的转移特性、输出特性和击穿特性等关键参数,分析了各参数对性能的影响规律。研究结果为功率半导体器件的仿真建模提供了规范化参考,有助于优化SOI LDMOS的性能设计。

huanghm88的专栏 127

第四部分:VTK常用类详解(第96章 vtkCaptionActor2D标题演员类)

VTK标题演员实现3D场景标注功能 摘要:vtkCaptionActor2D是VTK可视化工具包中的标题标注组件,提供混合2D/3D的文本标注功能。该组件通过连接线将文本标注与场景中的3D点关联,支持多行文本显示、自定义文本样式和动态定位。文章详细介绍了标题演员的设计原理、坐标系统控制方法、文本内容管理和大小自适应机制,并展示了在3D模型标注、数据可视化和交互场景中的典型应用。标题演员通过组合文本、边框和连接线组件,实现了灵活多样的场景标注方案,是科学计算可视化中重要的标注工具。

仰望星空的博客 251

【XAI】透视深度学习:CNN与Transformer的可解释性方法

深度学习模型的可解释性方法解析:本文探讨了CNN和Transformer两类主流模型的可解释性技术。针对CNN,介绍了显著性图、类激活图(CAM/Grad-CAM)和基于扰动的方法,通过可视化重要像素区域揭示决策依据。对于Transformer,重点分析了注意力机制可视化及其在文本处理中的应用,并介绍了积分梯度等归因方法。文章包含详细的Python实现示例(使用Captum库),涵盖从MNIST图像显著性分析到BERT文本注意力可视化,为初学者提供了可操作的技术指南。这些方法有助于增强模型透明度,提升AI系

u012133341的博客 377

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

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

上一篇: PostgreSQL 主键优化:从自增ID到雪花算法的实战迁移
下一篇: LaTeX 高效写作:利用条件编译实现毕业论文模块化开发与调试
星座呦呦秀
博客等级 码龄10年 40粉丝 1523原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值