当前位置:首页 > 内存 > 正文

内存复用功能有哪几种

  • 内存
  • 2024-08-01 13:35:43
  • 5108

一、mfc内存复用技术有哪些内存分配、内存替换、内存泡沫。
内存分区:读取时从父卷读取,修改时写入差异卷。这就是内存共享技术。
内存更换:当内存比较小时,会在磁盘上开辟一个空间,用于内存更换一段时间,时间越长,未使用的数据就越冷。
内存泡沫:通过压榨其他虚拟机的内存,将内存释放给其他内存使用率较高的虚拟机。
二、如何处理java常量字符串过长的问题?

解决Java常量字符串过长问题的主要方法如下:

1.使用常量池:Java语言提供了常量池来存储字符串常量。高效管理和重用渠道资源。当你将一个字符串常量声明为文字时,JVM会自动将其放入常量池中,以避免重复创建相同的字符串对象。因此,建议以这种方式定义长字符串常量。

2.使用StringBuilder或StringBuffer:当字符串长度过长或者程序执行过程中需要拼接字符串时,可以考虑使用StringBuilder或StringBuffer类。这两个类提供灵活的字符串连接操作,与使用字符串连接表示法相比,可以减少内存开销并提高性能。当您需要在程序中创建长而复杂的字符串时,这特别有用。

3.使用文件读取:如果常量字符串太长,消耗大量内存或难以直接处理,则可以考虑从外部文件读取字符串。通过读取文件内容,可以动态获取长字符串,而不占用太多内存空间。这种方法适合存储和管理非常大的文本数据。

详细解释:

Java中的字符串常量池是一个重要的特性,它允许共享和重用具有相同内容的字符串对象。通过将长字符串放入常量池中,可以保证不同代码段中引用同一个字符串对象,避免重复创建和内存浪费。这对于经常使用的长字符串常量非常有效。

当程序需要动态构造长字符串或者在程序运行过程中频繁拼接时,StringBuilder和StringBuffer成为不错的选择。它们内部使用可变字符数组来存储数据,并通过追加等方法进行拼接操作。这种方法比直接使用字符串拼接符号效率更高。

在某些情况下,如果长字符串中的数据太大或太复杂而难以处理,那么直接将其存储在代码中是不合适的。此时你可能会考虑将这部分数据存储在外部文件中,并在程序运行时通过读取文件内容来获取这些长字符串。此方法可确保有效的内存使用,并且可以处理更大量的文本数据。通过合理的文件读写逻辑,可以高效地管理和使用这些长字符串资源。


三、高性能框架都会复用对象,它做到了开箱即用上一篇文章httprouter路由框架为什么高性能提到,高性能的原因在于减少了内存分配。因为分配的内存是在堆上分配的,所以调用mallocgc函数会产生性能成本。
Httprouter使用来减少内存分配和GC消耗。
那么为什么可以做到这一点呢?为降低性能消耗做了哪些工作?
是一组可以独立保存和检索的临时对象。Pool中存储的任何对象都可能会被自动删除,并且用户不会被告知此删除过程。
Pool的目的是缓存已分配但未使用的对象以供以后重用,从而减少垃圾收集的压力。该池是并发安全的,这意味着它可以轻松创建高效、线程安全的存储池。
一个例子是fmt包。Pool维护一个动态大小的临时输出缓冲区,该缓冲区在加载期间扩展(打印多个goroutine)并在休息时折叠。
那么当你在使用对象的时候申请一个对象,Get方法就会返回Pool中已经存在的对象。否则,使用New方法来初始化对象。
当使用完毕后,调用Put方法将对象返回到Pool中。
池只有3个接口,可用于所有对象类型。
那么我们思考一个问题:使用有什么好处?
我们看一个例子
最终的打印结果
多次打印可能会产生不同的结果,但数量并不大。如果不使用Pool来申请,而是直接使用buffer:=make([]byte,1024)来申请内存,那么就会申请1024*1024个对象,造成很大的浪费。Pool就是此类对象的重用。
既然我们知道了重用对象的好处,那么是如何实现这个功能的呢?
首先我们看一下Pool的结构
poolLocal管理池中缓存项的关键结构Pool
这个pin功能包含电流。goroutine在P上,不允许调度,返回P的本地池和P的标识符。
这个indexLocal实际上是一个指向本地池的索引的指针
通常,只有在第一次执行时ize为0时,w才会被执行。直接使用if返回到本地池。
pinSlow是将池存在allPools表中
先解锁,然后添加全局互斥量
allPools是池全局,oldPool这是受害者使用的水池。
然后再次持有P上的goroutine,并决定是否直接返回本地池。
使用ROCS(0)获取处理器的数量,也就是P的数量。
这里再详细说明一下,runtime_procPin实际上是对运行时包下的procPin。
procPin的目的是抢占G的执行权限,也就是说G不能离开M。实际的内核是++,在newstack函数中有这么一段代码<。br/>
这里>0,所以只能让G继续运行
runtime_procUnpin函数可以猜测是关于让--。
恢复私有对象。如果移除的对象为空,则尝试从共享队列中检索它。如果还是零,就从对方P的队列中获取,或者收集。受害者的。
如果上述地方不存在该对象,则调用New函数初始化一个对象并返回它
看到这里,你可能会有点困惑。只有这两个。此方法不使用受害者。
秘密在于它会在每次GC期间注册init函数并调用poolCleanup函数,这意味着每轮GC都会清理所有池。
poolCleanup功能包括迁移池
1。在读取数据时是安全的,它会包含当前的goroutine并且不会被中断
/>
2.复制后无法使用,因为nocopy
3。不适合长套接字连接或连接池等,因为无法知道连接池的各个名称,因此可以随时释放连接池元素。
4.从中删除的对象在使用后必须返回到池中。