- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我一直在使用 LodePNG 的 lodepng_encode24_file
对一些 24 位 RGB 图像文件进行编码,到目前为止效果非常好。但是,我注意到当我向它提供大于 15360*15360 像素大小的数据集时它似乎崩溃了(14336*14336 像素图像编码良好)。
可以通过简单地替换行来获得 32 位情况下此行为的最小示例(其中崩溃前的最大大小略低)
unsigned width = 512, height = 512;
与
unsigned width = 1024*14, height = 1024*14;
在LodePNG's example_encode.c file , 并执行它。
我以前遇到过 C 代码崩溃的问题,因为我将大型数组分配给堆栈内存(其最大大小通常在 2MB 左右)而不是堆内存,所以作为 C 的新用户,我的第一直觉是看看是否堆内存大小有上限。
然而,according to this answer ,堆内存没有限制,所以一定是其他地方出了问题。
我的第二个猜测是崩溃是由于 PNG 格式本身支持的最大图像尺寸的固有限制。然而,according to this answer及其下方的评论,PNG 支持的最大文件大小约为 4,000,000,000 * 4,000,000,000 像素,因此这也不是罪魁祸首。
有没有人猜到可能出了什么问题?其他人在尝试时是否能够重现此错误?
编辑:就 RAM 消耗而言,我有 8GB RAM,减去硬件保留、使用中、修改和备用内存(Windows 资源监视器实用程序使用的术语)我进行计算时大约有 4GB RAM 可用。对于 15000*15000 大小的 32 位图像,需要不到 1GB。同样,当我成功编码 14000*14000 24 位图像时,我的空闲 RAM 在编码过程的任何时候都不会低于 3GB,所以我认为 RAM 耗尽不是问题。
最佳答案
我相信您低估了程序使用的内存量。假设您在 Windows 上,那么您可能只有 2 GB 的内存可供进程使用(请参阅 here )。然后,您为 14336x14336 图像分配一个 882 MB 的大块。 LodePNG 代码然后进行更多分配,最有可能等于或大于此图像大小。
我只追踪了 LodePNG code手动但它似乎在内存中创建一个缓冲区并以 block 的形式写入该缓冲区。它在重新分配时进行最小调整(在 lodepng_chunk_append()
中,仅足以容纳数据加上 12 个字节),这意味着它将不得不进行大量重新分配。这可能(或最终将)将内存碎片化到无法使用非常大的缓冲区的程度。
即使堆内存没有碎片,想想当您尝试将 800MB 缓冲区 realloc()
到 801MB 缓冲区时可能会发生什么。如果堆管理器是“智能”的,它可能会起作用,但天真的一个将需要总共 1601MB ......如果您的堆大小为 2000MB 并且您已经使用了其中的 822MB,则这不可用。
其中很多(大部分)都是推测,但您可以自己做一些测试来模拟分配和重新分配几个大内存块,看看您是否可以重现内存不足的情况。
附录:虽然上述内容可能是正确的,但实际上并不是本例中崩溃的原因。从实际运行和跟踪代码来看,问题出在 LodePng.c 中的第 5558 行:
size_t size = (w * h * lodepng_get_bpp(&info.color) + 7) / 8;
当 lodepng_get_bpp()
返回 24 时,当 w * h
大于 178,956,970 时,此计算会导致整数溢出。对于方形图像,这是 13378 x 13378。这导致输出缓冲区被分配不正确的大小,从而在稍后写入时缓冲区溢出。
一个快速的解决方法是将这一行更改为:
size_t size = (size_t) ((unsigned long long) w * h * lodepng_get_bpp(&info.color) / 8 + 1);
尽管我不确定这是否适用于所有 BPP 值并且它仍然存在溢出问题,尽管尺寸较大。我建议联系 LodePNG 的作者以实现适当的修复。
关于c - LodePNG 在编码大于 15000 * 15000 像素的 PNG 文件时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25490332/
我不太确定为什么较大字符串(“cat”和“dog”)的答案不一致。我正在用链接列表和模板的使用做一些事情。我的好奇心促使我修改模板和函数重载。如果有人能解释发生了什么,我将不胜感激。谢谢你。 #inc
目前我必须编写这样的查询 SELECT * FROM table WHERE value1 > 5000 OR value2 > 5000 OR value3 > 5000 OR value4 > 5
我想创建一个如下所示的查询,但我不确定如何正确编码, 我希望它在开始时间的 1 小时内返回所有预订,这是我想出的: SELECT BookingId, StartTime FROM Booking W
这个问题已经有答案了: How to check if a number is between two values? (12 个回答) 已关闭 6 年前。 我目前正在 Codecademy 上学习
我想验证用户输入。如果用户输入的数字大于 3,则应抛出错误“Too high”,如果小于 0.15,则应抛出“Too low”错误。如果它在 3 到 0.15 之间,那么它应该显示“好的”。 我的代码
我有一个拖动脚本,我在其中拖动 div.slider,我正在跟踪 div.slider 的“左”值,并在它大于 68 时让它淡出,但问题是它当它达到 6 而不是 68 时淡出。如果我将数字更改为 85
是否有一种常见的模式如何在数据库(postgresql)中存储这样的条件,然后以简单的方式从数据库中获取这些数据,并在前端将其与我们在前端的值 SE 进行比较(以获得正确的“值” "): condit
如何大于/小于内部工作 如果我将 5 与 100 与 5 与 2,147,483,647 (Integer.MAX_VALUE) 进行比较,性能会受到多大影响 5 < 100 and 5 < Inte
当我运行此查询时它有效 SELECT sum( amount ) AS balance FROM balance WHERE amount >= 100 但是当我想过滤用户 ID 时,它返回 NULL
我有下表: account(id, balance, bank_branch) 我想选择账户余额大于其 bank_branch 平均余额的所有账户 我试过了 Select id from accoun
你们有没有人知道如何搜索所有大于指定数字的数字? 例如:所有单据编号>65 我试过这样:documentNumber: [65 TO *] 但我收到异常,因为 lucene 期望解析一个没有 * 的数
我正在使用 Prolog 算法,并且有一个生成抽象语法树的程序,例如 plus(num(1),num(2))这只是 1+2 .这是通过使用 DCG 来完成的。在这个例子中 plus(num(1),nu
是否使用 Sin(720) 或 Cos(1440)(以度为单位的角度)? 无论是在计算机编程中还是在任何其他情况下? 一般来说,是否有任何角度的 Sin/Cosine/Tan 使用 大于360? 在物
我发现了一些与此相关的问题,但没有一个真正回答了我的问题。 我有一个像这样的表格文件: 2 10610 0 0 0 0.0105292 2 10649 0 0 0
我是 Prolog 的新手,我正在尝试解决这个练习: Define a predicate greater_than/2 that takes two numerals in the notation
我想选择具有出现次数的不同键,此查询似乎有效: SELECT ItemMetaData.KEY, ItemMetaData.VALUE, count(*) FROM ItemMetaData GROU
我需要存储和使用大于 ULLONG_MAX 的数值。 我需要对这些值进行算术运算,所以我认为存储为 char** 不是一个选项。 在这些情况下,有没有办法动态创建额外的 long 前缀? 谢谢大家。根
我是 Prolog 的新手,我正在尝试解决这个练习: Define a predicate greater_than/2 that takes two numerals in the notation
处理已知大小但大于 64 位的位掩码(即执行所有位操作)的最有效的数据结构是什么? 字节[]? 大整数?完全是别的东西吗? 需要与 Java 7 兼容,并且对于诸如此类的事情应该很快(或者至少与合理预
编辑:抱歉进行了许多编辑。我自己都忘记写了什么了。 我使用 JPanel,将 BoxLayout 作为 JFrame 的根面板。我向此根面板添加了另外两个面板:带有 FlowLayou 的 Butto
我是一名优秀的程序员,十分优秀!