32位unix时间戳哪一年耗尽

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了32位unix时间戳哪一年耗尽相关的知识,希望对你有一定的参考价值。

格林尼治时间2038年1月19日凌晨03:14:07(北京时间:2038年1月19日中午11:14:07)。2038年问题可能会导致某些软件在2038年无法正常工作,所有使用POSIX时间表示时间的程序都将受其影响。

因为它们的时间起点是格林尼治时间1970年1月1日0时0分0秒,依照此“time_t”标准,在此格式能被表示的最后时间是第2147483647秒(代表格林尼治时间2038年1月19日凌晨03:14:07)。

扩展资料:

在32位系统上,time_t能表示的最大值为0x7ffffffff,当time_t取最大值时表示系统时间为2038-01-19 03:14:07,但时间再往后走时,那time_t会溢出变成一个负值,此时系统时间会倒流回到1901年,届时操作系统和上层软件都会运行错出。

对于服务器来说,早早就换到了64系统操作系统,2038年问题不复存在。而对于嵌入式设备来说,现在还有大量32位系统在全球各地运行,谁也无法保证这些系统在2038年之前就能光荣退役。

另外对于64位操作系统,上面还会运行着32位的应用程序,它的2038年问题一样对人们造成威胁,不可小视。

参考资料来源:百度百科-2038年问题

参考技术A 此类系统的Unix时间戳最多可以使用到格林威治时间2038年01月19日03时14分07秒(二进制:01111111 11111111 11111111 11111111)。其后一秒,二进制数字会变为10000000 00000000 00000000 00000000,
发生溢出错误,造成系统将时间误解为1901年12月13日20时45分52秒。这很可能会引起软件故障,甚至是系统瘫痪。使用64位二进制数字表示时间
的系统(最多可以使用到格林威治时间292,277,026,596年12月04日15时30分08秒)则基本不会遇到这类溢出问题。本回答被提问者和网友采纳

在 32 位 Linux 中无法耗尽物理内存

【中文标题】在 32 位 Linux 中无法耗尽物理内存【英文标题】:Cannot Exhaust Physical Memory in 32 bit Linux 【发布时间】:2018-05-02 16:30:23 【问题描述】:

所以我有一个有趣的基于操作系统的问题给你。在过去的几个小时里,我一直在与我认识的任何有 C 编程经验的人交谈,但似乎没有人能够就为什么会发生这种行为提出明确的答案。

我有一个故意设计为导致严重内存泄漏的程序(例如,当您在分配内存后不释放内存时会发生什么情况)。在 64 位操作系统(Windows、Linux 等)上,它会做它应该做的事情。它填充物理内存,然后填充操作系统的交换空间。在 Linux 中,该进程随后被操作系统终止。然而,在 Windows 中,它不是,它会继续运行。最终的结果是系统崩溃。

代码如下:

#include <stdlib.h>
#include <stdio.h>

void main()

    while(1)
    
        int *a;
        a = (int*)calloc(65536, 4);
    

但是,如果您在 32 位 Linux 发行版上编译并运行此代码,则它对物理内存的使用完全没有影响。它使用了我分配的 4 GB RAM 的大约 1%,之后就再也没有增加。我没有要测试的 32 位 Windows 的合法副本,所以我不能确定这也发生在 32 位 Windows 上。

谁能解释一下为什么使用 calloc 会填满 64 位 Linux 操作系统的物理内存,而不是 32 位 Linux 操作系统?

【问题讨论】:

这是 Linux 的一个“特性”。您可以根据需要分配尽可能多的内存,只要您实际上不使用。尝试在您分配的内存中写入一个随机字节,您将看到您的系统很快就会开始终止随机进程。 你永远不会使用内存。这可以在多个级别上捕获。编译器已经可以消除代码,它没有可观察到的行为。操作系统可能会延迟页面分配,直到出现页面错误。等等...要查看某些内容,请使用0 以外的一些数据填充内存,这可能是一种特殊情况。 好的,我可以修改它以使用 malloc 和 for 循环遍历分配值的数组,这是其他人所做的,它会产生相同的结果。其次,这并不能解释为什么这段代码填充 64 位 Linux 操作系统的主内存。 名称是overcommiting 我也不认为过度使用是我在这里遇到的问题。我的物理台式电脑有 16 GB 的 RAM。此虚拟机使用 4 GB。 en.wikipedia.org/wiki/Memory_overcommitment 【参考方案1】:

malloccalloc 函数在技术上并不分配内存,尽管它们的名称。它们实际上为您的程序地址空间的一部分分配了操作系统级别的读/写权限。这是一个细微的差别,大部分时间并不相关。

这个程序,正如所写的,只消耗地址空间。最终,calloc 将开始返回 NULL,但程序将继续运行。

#include <stdlib.h>
// Note main should be int.
int main() 
    while (1) 
        // Note calloc should not be cast.
        int *a = calloc(65536, sizeof(int));
    

如果你写入从 calloc 返回的地址,它将强制内核分配内存来支持这些地址。

#include <stdlib.h>
#include <string.h>
int main() 
    size_t size = 65536 * 4;
    while (1) 
        // Allocates address space.
        void *p = calloc(size, 1);
        // Forces the address space to have allocated memory behind it.
        memset(p, 0, size);
    

仅写入从calloc 返回的块中的单个位置是不够的,因为分配实际内存的粒度是 4 KiB(页面大小...... 4 KiB 是最常见的)。因此,您只需写入每一页即可。

64 位的情况如何?

分配地址空间需要一些记账开销。在 64 位系统上,您会获得 40 或 48 位的地址空间,其中大约一半可以分配给程序,即至少 8 TiB。在 32 位系统上,这达到 2 GiB 左右(取决于内核配置)。

因此,在 64 位系统上,您可以分配 ~8 TiB,而在 32 位系统上,您可以分配 ~2 GiB,而开销是导致问题的原因。每次调用malloccalloc 通常都会产生少量开销。

另见Why malloc+memset is slower than calloc?

【讨论】:

如果这是真的,那为什么它会淹没物理内存并最终淹没 64 位操作系统的交换空间? @LC14199 因为这就是现代内存管理的完成方式。您分配的内存是虚拟的,直到您实际写入它,然后需要一个物理页面(实际的内存块)并且 RAM 使用量会增加。拿一本操作系统书籍,阅读内存管理一章。 @TonyTannous,calloc 在分配内存后写入内存。它使用 0 值初始化所有内存。因此,这使得内存不再是虚拟的。或者至少,我目前是这样理解的。 @LC14199:这是不正确的。 calloc 在分配内存后并不总是写入内存。 tutorialspoint.com/c_standard_library/c_function_calloc.htm 根据本页的定义,“malloc 和 calloc 的区别在于 malloc 不会将内存设置为零,而 calloc 会将分配的内存设置为零。”所以现在我很想知道它到底是如何工作的。我现在正在测试你的代码。然后当然是这个:***.com/questions/1538420/…

以上是关于32位unix时间戳哪一年耗尽的主要内容,如果未能解决你的问题,请参考以下文章

UNIX时间戳手工计算方法

Java 获取 Unix时间戳

如何在不同编程语言中获取现在的Unix时间戳(Unix timestamp)?

如何将 13 位 Unix 时间戳转换为日期和时间?

php如何取得十三位unix时间戳

当碰到unix纪元问题时strtotime怎么转时间戳(DateTime类的使用方法)