Libérer la mémoire d'un objet volumineux
L'éditeur PHP Youzi vous présente une technique pour optimiser l'utilisation de la mémoire : libérer la mémoire des objets volumineux. Au cours du processus de développement, nous créons souvent des objets volumineux, tels que de grands tableaux ou des résultats de requêtes de base de données volumineux, et ces objets occupent beaucoup de ressources mémoire. Lorsque nous avons fini d'utiliser ces objets, c'est une bonne habitude de programmation de libérer la mémoire à temps. Cet article vous montrera comment libérer de la mémoire des objets volumineux pour améliorer les performances et l'efficacité des applications.
Contenu de la question
J'ai rencontré quelque chose que je ne comprends pas. J'espère que vous pourrez tous aider !
Ressources :
- https://medium.com/@chaewonkong/solving-memory-leak-issues-in-go-http-clients-ba0b04574a83
- https://www.golinuxcloud.com/golang-garbage-collector/
J'ai lu dans quelques articles que nous pourrions simplifier le travail de gc en définissant de grandes tranches et cartes (je suppose que cela s'applique à tous les types de référence) sur nil
une fois que nous n'en aurons plus besoin. Voici l'un des exemples que j'ai lus :
func ProcessResponse(resp *http.Response) error { data, err := ioutil.ReadAll(resp.Body) if err != nil { return err } // Process data here data = nil // Release memory return nil }
Si je comprends bien, lorsque la fonction processresponse
完成时,data
变量将超出范围,基本上将不再存在。然后,gc 将验证是否没有对 []byte
切片(data
pointe vers une référence à la tranche), la mémoire sera effacée.
Définissez data
sur data
设置为 nil
Comment améliorer le garbage collection ?
Merci !
Solution de contournement
Comme d'autres l'ont déjà souligné : définirdata = nil
不会改变 gc 方面的任何内容。 go 编译器将应用优化,并且 golang 的垃圾收集器在不同的阶段工作。用最简单的术语(有许多遗漏和过度简化):设置 data = nil
avant de revenir et supprimer toutes les références à la tranche sous-jacente ne déclenche pas une libération de mémoire de type atomique qui n'est plus référencée. Dès qu'une tranche n'est plus référencée, elle est marquée comme telle et la mémoire associée n'est libérée qu'au prochain scan.
Le garbage collection est un problème difficile, en grande partie parce que ce n'est pas le genre de problème pour lequel une solution optimale produit les meilleurs résultats pour tous les cas d'utilisation. Le runtime go a beaucoup évolué au fil des années, et le travail important est effectué sur le garbage collector du runtime. Le résultat est que, dans de rares cas, un simple somevar = nil
fera même une petite différence, et encore moins une différence notable.
Si vous recherchez quelques conseils simples de type règle empirique qui pourraient avoir un impact sur la surcharge d'exécution associée au garbage collection (ou à la gestion de la mémoire d'exécution en général), je sais que cette phrase semble couvrir vaguement celle de votre questions :
Il est suggéré de simplifier le travail de gc en configurant de grandes tranches et des mappages
Cela peut donner des résultats significatifs lors de l'analyse du code. En supposant que vous lisez une grande quantité de données qui doivent être traitées, ou que vous deviez effectuer un autre type d'opération par lots et renvoyer des tranches, il n'est pas rare que les gens écrivent quelque chose comme ceci :
func processstuff(input []sometypes) []resulttypes { data := []resulttypes{} for _, in := range input { data = append(data, processt(in)) } return data }
Facile à optimiser en changeant le code en :
func processstuff(input []sometypes) []resulttypes { data := make([]resulttypes, 0, len(input)) // set cap for _, in := range input { data = append(data, processt(in)) } return data }
Ce qui se passe lors de la première implémentation, c'est que lorsque vous utilisez len
和 cap
为 0 创建一个切片。第一次调用 append
, vous dépassez la capacité actuelle de la tranche, ce qui oblige le runtime à allouer de la mémoire. Comme expliqué ici, le calcul de la nouvelle capacité est assez simple, la mémoire est allouée et les données sont copiées :
t := make([]byte, len(s), (cap(s)+1)*2) copy(t, s)
Essentiellement, chaque fois que la tranche à ajouter est pleine (c'est-à-dire len
== cap
)调用 append
时,您将分配一个可容纳: (len + 1) * 2
元素的新切片。知道在第一个示例中 data
以 len
和 cap
== 0 pour commencer, voyons ce que cela signifie :
1st iteration: append creates slice with cap (0+1) *2, data is now len 1, cap 2 2nd iteration: append adds to data, now has len 2, cap 2 3rd iteration: append allocates a new slice with cap (2 + 1) *2, copies the 2 elements from data to this slice and adds the third, data is now reassigned to a slice with len 3, cap 6 4th-6th iterations: data grows to len 6, cap 6 7th iteration: same as 3rd iteration, although cap is (6 + 1) * 2, everything is copied over, data is reassigned a slice with len 7, cap 14
Si les structures de données dans la tranche sont volumineuses (c'est-à-dire de nombreuses structures imbriquées, beaucoup d'indirection, etc.), alors cette réallocation et cette copie fréquentes peuvent devenir assez coûteuses. Si votre code contient beaucoup de ces boucles, il commencera à apparaître dans pprof (vous commencerez à voir des appels prendre beaucoup de temps gcmalloc
). De plus, si vous traitiez 15 valeurs d'entrée, votre tranche de données ressemblerait à ceci :
dataslice { len: 15 cap: 30 data underlying_array[30] }
Cela signifie que vous allouerez de la mémoire pour 30 valeurs alors que vous n'en avez besoin que de 15, et que vous allouerez cette mémoire en 4 morceaux progressivement plus grands, en copiant les données à chaque réallocation.
En revanche, la deuxième implémentation allouera une tranche de données comme celle-ci avant la boucle :
data { len: 0 cap: 15 data underlying_array[15] }
Il est alloué une fois, donc aucune réallocation ni copie n'est requise, et la tranche renvoyée occupera la moitié de l'espace mémoire. En ce sens, nous allouons d’abord des blocs de mémoire plus grands au début pour réduire le nombre d’appels d’allocation et de copie incrémentielle requis plus tard, ce qui réduit globalement le coût d’exécution.
如果我不知道需要多少内存怎么办
这是一个公平的问题。这个例子并不总是适用。在这种情况下,我们知道需要多少个元素,并且可以相应地分配内存。有时,世界并不是这样运作的。如果您不知道最终需要多少数据,那么您可以:
- 做出有根据的猜测:gc 很困难,而且与您不同的是,编译器和 go 运行时缺乏模糊逻辑,人们必须提出现实、合理的猜测。有时它会像这样简单:“嗯,我从该数据源获取数据,我们只存储最后 n 个元素,所以最坏的情况下,我将处理 n 个元素” em>,有时它有点模糊,例如:您正在处理包含 sku、产品名称和库存数量的 csv。您知道 sku 的长度,可以假设库存数量为 1 到 5 位数字之间的整数,产品名称平均为 2-3 个单词长。英文单词的平均长度为 6 个字符,因此您可以粗略地了解 csv 行由多少字节组成:假设 sku == 10 个字符,80 个字节,产品描述 2.5 * 6 * 8 = 120 个字节,以及 ~ 4 个字节表示库存计数 + 2 个逗号和一个换行符,平均预期行长度为 207 个字节,为了谨慎起见,我们将其称为 200。统计输入文件,将其大小(以字节为单位)除以 200,您应该对行数有一个可用的、稍微保守的估计。在该代码末尾添加一些日志记录,比较上限与估计值,然后您可以相应地调整您的预测计算。
- 分析您的代码。有时,您会发现自己正在开发新功能或全新项目,而您没有历史数据可以依靠进行猜测。在这种情况下,您可以简单地猜测,运行一些测试场景,或者启动一个测试环境来提供您的代码生产数据版本并分析代码。当您正在主动分析一两个切片/映射的内存使用/运行时成本时,我必须强调这是优化。仅当这是瓶颈或明显问题时(例如,运行时内存分配阻碍了整体分析),您才应该在这方面花费时间。在绝大多数情况下,这种级别的优化将牢牢地属于微优化的范畴。 坚持80-20原则
回顾
不,将一个简单的切片变量设置为 nil 在 99% 的情况下不会产生太大影响。创建和附加到地图/切片时,更可能产生影响的是通过使用 make()
+ 指定合理的 cap
值来减少无关分配。其他可以产生影响的事情是使用指针类型/接收器,尽管这是一个需要深入研究的更复杂的主题。现在,我只想说,我一直在开发一个代码库,该代码库必须对远远超出典型 uint64
范围的数字进行操作,不幸的是,我们必须能够以更精确的方式使用小数比 float64
将允许。我们通过使用像 holiman/uint256 这样的东西解决了 uint64
问题,它使用指针接收器,并解决shopspring/decimal 的十进制问题,它使用值接收器并复制所有内容。在花费大量时间优化代码之后,我们已经达到了使用小数时不断复制值的性能影响已成为问题的地步。看看这些包如何实现加法等简单操作,并尝试找出哪个操作成本更高:
// original a, b := 1, 2 a += b // uint256 version a, b := uint256.NewUint(1), uint256.NewUint(2) a.Add(a, b) // decimal version a, b := decimal.NewFromInt(1), decimal.NewFromInt(2) a = a.Add(b)
这些只是我在最近的工作中花时间优化的几件事,但从中得到的最重要的一点是:
过早的优化是万恶之源
当您处理更复杂的问题/代码时,您需要花费大量精力来研究切片或映射的分配周期,因为潜在的瓶颈和优化需要付出很大的努力。您可以而且可以说应该采取措施避免过于浪费(例如,如果您知道所述切片的最终长度是多少,则设置切片上限),但您不应该浪费太多时间手工制作每一行,直到该代码的内存占用尽可能小。成本将是:代码更脆弱/更难以维护和阅读,整体性能可能会恶化(说真的,你可以相信 go 运行时会做得很好),大量的血、汗和泪水,以及急剧下降在生产力方面。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds

1. Ouvrez Xiaohongshu, cliquez sur Moi dans le coin inférieur droit 2. Cliquez sur l'icône des paramètres, cliquez sur Général 3. Cliquez sur Vider le cache

Le réglage fin local des modèles de classe Deepseek est confronté au défi des ressources informatiques insuffisantes et de l'expertise. Pour relever ces défis, les stratégies suivantes peuvent être adoptées: quantification du modèle: convertir les paramètres du modèle en entiers à faible précision, réduisant l'empreinte de la mémoire. Utilisez des modèles plus petits: sélectionnez un modèle pré-entraîné avec des paramètres plus petits pour un réglage fin local plus facile. Sélection des données et prétraitement: sélectionnez des données de haute qualité et effectuez un prétraitement approprié pour éviter une mauvaise qualité des données affectant l'efficacité du modèle. Formation par lots: pour les grands ensembles de données, chargez les données en lots de formation pour éviter le débordement de la mémoire. Accélération avec GPU: Utilisez des cartes graphiques indépendantes pour accélérer le processus de formation et raccourcir le temps de formation.

Le manque de mémoire sur les téléphones mobiles Huawei est devenu un problème courant auquel sont confrontés de nombreux utilisateurs, avec l'augmentation des applications mobiles et des fichiers multimédias. Pour aider les utilisateurs à utiliser pleinement l'espace de stockage de leurs téléphones mobiles, cet article présentera quelques méthodes pratiques pour résoudre le problème de mémoire insuffisante sur les téléphones mobiles Huawei. 1. Nettoyer le cache : enregistrements d'historique et données invalides pour libérer de l'espace mémoire et effacer les fichiers temporaires générés par les applications. Recherchez « Stockage » dans les paramètres de votre téléphone Huawei, cliquez sur « Vider le cache » et sélectionnez le bouton « Vider le cache » pour supprimer les fichiers de cache de l'application. 2. Désinstallez les applications rarement utilisées : pour libérer de l'espace mémoire, supprimez certaines applications rarement utilisées. Faites glisser vers le haut de l'écran du téléphone, appuyez longuement sur l'icône « Désinstaller » de l'application que vous souhaitez supprimer, puis cliquez sur le bouton de confirmation pour terminer la désinstallation. 3.Application mobile pour

Écrit à l'avant et point de départ Le paradigme de bout en bout utilise un cadre unifié pour réaliser plusieurs tâches dans les systèmes de conduite autonome. Malgré la simplicité et la clarté de ce paradigme, les performances des méthodes de conduite autonome de bout en bout sur les sous-tâches sont encore loin derrière les méthodes à tâche unique. Dans le même temps, les fonctionnalités de vue à vol d'oiseau (BEV) denses, largement utilisées dans les méthodes de bout en bout précédentes, rendent difficile l'adaptation à davantage de modalités ou de tâches. Un paradigme de conduite autonome de bout en bout (SparseAD) centré sur la recherche clairsemée est proposé ici, dans lequel la recherche clairsemée représente entièrement l'ensemble du scénario de conduite, y compris l'espace, le temps et les tâches, sans aucune représentation BEV dense. Plus précisément, une architecture clairsemée unifiée est conçue pour la connaissance des tâches, notamment la détection, le suivi et la cartographie en ligne. De plus, lourd

Qu'est-ce que « Autre » est affiché dans la mémoire du téléphone mobile ? L'« Autre » dans la mémoire du téléphone mobile contient deux parties : les fichiers système du téléphone mobile. Fichiers générés automatiquement lors du téléchargement d'un logiciel sur votre téléphone mobile. Comment effacer la mémoire occupée par « l'autre » partie du stockage du téléphone mobile : Les fichiers système appartenant au téléphone mobile sont généralement livrés avec des fonctions de protection intégrées et ne peuvent pas être effacés. La classification dans la capacité du téléphone mobile concerne principalement les fichiers cache du téléphone mobile, qui sont divisés dans les catégories suivantes : Chemin du dossier du répertoire cache : c : Systemcache, qui peut être effacé régulièrement. Il est recommandé d'effacer tous les dossiers temporaires du répertoire temporaire. Pour comprendre simplement, les autres sont des types de fichiers que le téléphone ne peut pas reconnaître. Différents téléphones mobiles et même différents environnements logiciels sont différents. De plus, le cache du programme sera traité comme s'il s'agissait d'autre chose. autre dans le téléphone mobile

1. Tout d’abord, entrez dans le navigateur Edge et cliquez sur les trois points dans le coin supérieur droit. 2. Ensuite, sélectionnez [Extensions] dans la barre des tâches. 3. Ensuite, fermez ou désinstallez les plug-ins dont vous n'avez pas besoin.

Les grands modèles de langage open source familiers tels que Llama3 lancé par Meta, les modèles Mistral et Mixtral lancés par MistralAI et Jamba lancé par AI21 Lab sont devenus des concurrents d'OpenAI. Dans la plupart des cas, les utilisateurs doivent affiner ces modèles open source en fonction de leurs propres données pour libérer pleinement le potentiel du modèle. Il n'est pas difficile d'affiner un grand modèle de langage (comme Mistral) par rapport à un petit en utilisant Q-Learning sur un seul GPU, mais le réglage efficace d'un grand modèle comme Llama370b ou Mixtral est resté un défi jusqu'à présent. . C'est pourquoi Philipp Sch, directeur technique de HuggingFace

Selon un rapport d'enquête TrendForce, la vague de l'IA a un impact significatif sur les marchés de la mémoire DRAM et de la mémoire flash NAND. Dans l'actualité de ce site du 7 mai, TrendForce a déclaré aujourd'hui dans son dernier rapport de recherche que l'agence avait augmenté les augmentations de prix contractuels pour deux types de produits de stockage ce trimestre. Plus précisément, TrendForce avait initialement estimé que le prix du contrat de mémoire DRAM au deuxième trimestre 2024 augmenterait de 3 à 8 %, et l'estime désormais à 13 à 18 % en termes de mémoire flash NAND, l'estimation initiale augmentera de 13 à 8 % ; 18 %, et la nouvelle estimation est de 15 % ~ 20 %, seul eMMC/UFS a une augmentation inférieure de 10 %. ▲Source de l'image TrendForce TrendForce a déclaré que l'agence prévoyait initialement de continuer à
