简易的c垃圾收集器

Java 的七种垃圾收集器 用C或C++这样的编程语言写一个应用时,需要编写代码来销毁内存中不再需要的对象。当应用程序扩展得越来越复杂时,未使用对象被忽略释放的可能性就越大。这会导致内存泄露,最终内存耗尽,在某个时刻将没有更多的内存可以分配。结果就是应用程序运行失败并出现OutOfMemoryError错误。但在Java中,垃圾收集器GarbageCollection(GC)会在程序执行过程中自动运行,减轻了手动分配内存和可能的内存泄漏的任务。... 阅读详情

一个简易的c垃圾收集器

  262人阅读  评论(9)  收藏  举报

      这段时间试着实现了一个简易的C语言垃圾收集器,代码不多,但对我的经验而言,确实费了不少心思。
      这里感谢云风兄的开源:云风:blog.codingnow.com/2008/06/gc_for_c.html
      以及LOGOS兄的对yfgc的解析和实现的一个概念版本:LOGOS:www.cppblog.com/darkdestiny
      话说我知道自己的实现里面,有很多考虑不足的地方。但还是决定贴出来,讲述的我实现的思想,有不足的地方大家指出来也好纠正。
       大家知道垃圾收集技术主要分为以下几种,他们有各自的优点与缺点:
       1、引用技术(Reference Counting)
       2、标记清除(Mark-Sweep)
       3、标记整理/紧缩(Mark-Compact)
       4、结点复制(Copying)
       5、分代收集(Generational Collecting)
       这里我就不详述各种思想了,google上有。我的需求是:要求垃圾收集能自然的解决循环引用的问题,占用的空间不要太多,轻量级的实现,解决内存碎片的问题。
       这里我选用的是标记清除算法,内存分配使用内存池。
       首先还是给出内存池的接口,实现在我之前的文章中有讲,就不贴出来了。内存池的实现借鉴了sgi stl的实现思路。

Code:
  1. #ifndef _MEM_POOL_H   
  2. #define _MEM_POOL_H   
  3.   
  4. #include <stddef.h>   
  5.   
  6. void *mem_malloc(size_t n);   
  7. void mem_free(void *p, size_t n);   
  8. void *mem_realloc(void* ptr, size_t new_sz, size_t old_sz);   
  9.   
  10. #endif   

    然后看gc的接口:

Code:
  1. #ifndef GARBAGE_COLLECTOR_H   
  2. #define GARBAGE_COLLECTOR_H   
  3.   
  4. #include <stddef.h>   
  5.   
  6. #define my_malloc mem_malloc   
  7. #define my_free mem_free   
  8. #define my_realloc mem_realloc   
  9.   
  10. /* define the level of node */  
  11. #define NODE_ROOT_LEVEL 0 /* the node is global variable or in main() */   
  12. #define NODE_NOW_LEVEL 1  /* the node is just use in  present fucntion */   
  13. #define NODE_PRE_LEVEL 2  /* the node is be referenced by call function */   
  14.   
  15.   
  16. void gc_init();   
  17. void gc_exit();   
  18.   
  19. void func_end(void *p, ...);   
  20. void gc_link(void *p, int level);   
  21.   
  22. /* gc will mark the memory in gc_enter/gc_leave for collect later */  
  23. void gc_enter();   
  24. void gc_leave();   
  25.   
  26. void gc_collect();   
  27.   
  28. void *gc_malloc(size_t sz, void (*finalizer)(void *));   
  29. void *gc_realloc(void *p, size_t sz);   
  30.   
  31. #endif   

  用到的数据结构:

Code:
  1. struct node {   
  2.     int mark;          /* mark for gc collect */  
  3.     int level;         /* the node leavel */  
  4.     struct {   
  5.         void *mem;     /* the pointer point to memory*/  
  6.         int size;      /* the size of memrory */  
  7.         void (*finalizer)(void *); /* destruction when the mem be free */  
  8.     }n;   
  9. };   
  10.   
  11. static struct {   
  12.     struct node *pool;   /* an array for store nodes */  
  13.     int size;            /* the size of pool */  
  14.     int free;            /* the next free node in pool */  
  15.     struct stack *stack; /* the stack used for store pointer in fuction */  
  16. } E;  

      这里 level 取值为:NODE_ROOT_LEVEL、NODE_NOW_LEVEL、NODE_PRE_LEVEL。 基于这样的考虑:我们知道动态分配一块内存,如果要延长其生命期,要么通过函数返回值传回,要么通过多级指针,或者直接挂到全局变量上。所以这个gc基于这样的策略:首先用户分配的内存块所在的结点 level 值初始化为NODE_NOW_LEVEL,如果用户需要延长其生命期到上一级函数或全局变量,那么调用 gc_link 并传入相应的 level 值。仅在其生命期需要延长至上一级函数时需要在函数结尾处(通过返回值传递动态内存时需要在 return 前)调用 func_end。func_end的作用是将该内存块的 level 值设置为NODE_NOW_LEVEL。
      知道了结点的生命期,标记就简单了。gc_leave负责将当前函数栈中的evel为NODE_NOW_LEVEL的结点标记为MARK_COLLECT,从而在 gc_collect 中回收。这里需要说的是main()函数中分配的内存和挂到全局变量的内存会在gc_exit中释放。
      大致过程知道了,下面就是具体实现了:

Code:
  1. #include <stdio.h>   
  2. #include <stdlib.h>   
  3. #include <stdarg.h>   
  4. #include <assert.h>   
  5. #include "stack.h"   
  6. #include "mem_pool.h"   
  7. #include "gc.h"   
  8.   
  9.   
  10.   
  11. #define POOL_INITIAL_NUMBER 1024 /* the initial number of nodes in pool */   
  12. #define POOL_MAX_NUMBER 4096     /* the max number of nodes in pool */   
  13.   
  14. #define STACK_SECTION_TAG NULL /* the tag to section the stack */   
  15.   
  16. #define MARK_INITIAL -1     /* the node initialed */   
  17. #define MARK_RESERVE 0      /* the node marked for reserve */   
  18. #define MARK_COLLECT 1      /* the node marked for collect */   
  19.   
  20. struct node {   
  21.     int mark;          /* mark for gc collect */  
  22.     int level;         /* the node leavel */  
  23.     struct {   
  24.         void *mem;     /* the pointer point to memory*/  
  25.         int size;      /* the size of memrory */  
  26.         void (*finalizer)(void *); /* destruction when the mem be free */  
  27.     }n;   
  28. };   
  29.   
  30. static struct {   
  31.     struct node *pool;   /* an array for store the pointer of node */  
  32.     int size;            /* the size of pool */  
  33.     int free;            /* the next free node in pool */  
  34.     struct stack *stack; /* the stack used for store pointer in fuction */  
  35. } E;   
  36.   
  37. static bool pool_compact()   
  38. {   
  39.     int i, j;   
  40.     struct node temp;   
  41.        
  42.     for (i = 0; i < E.free; i++) {   
  43.         if (E.pool[i].mark == MARK_INITIAL) {   
  44.             temp = E.pool[i];
  45.             for (j = E.free; j > i; j--) {   
  46.                 if (E.pool[j].mark != MARK_INITIAL) {   
  47.                     E.pool[i] = E.pool[j];   
  48.                     E.pool[j] = temp;   
  49.                     break;   
  50.                 }   
  51.             }   
  52.         }   
  53.     }   
  54.        
  55.     for (i = 0; i < E.size; i++) {   
  56.         if (E.pool[i].mark == MARK_INITIAL) {   
  57.             E.free = i;   
  58.             break;   
  59.         }   
  60.     }   
  61.        
  62.     return E.free >= E.size ? true : false;   
  63. }   
  64.   
  65. static void node_init()   
  66. {   
  67.     int i;   
  68.        
  69.     for (i = E.free; i < E.size; i++) {   
  70.         E.pool[i].mark = MARK_INITIAL;   
  71.         E.pool[i].level = NODE_NOW_LEVEL;   
  72.         E.pool[i].n.mem = NULL;   
  73.         E.pool[i].n.finalizer = NULL;   
  74.     }   
  75. }   
  76.   
  77. static void pool_expand()   
  78. {   
  79.     int expand_size;   
  80.     bool expand = false;   
  81.        
  82.     expand_size = E.size * 2;   
  83.     if (expand_size >= POOL_MAX_NUMBER * sizeof(struct node)) {   
  84.          expand = pool_compact();   
  85.     }    
  86.        
  87.     if (expand) {   
  88.         E.pool = (struct node *)my_realloc(E.pool, expand_size * sizeof(struct node),   
  89.              E.size * sizeof(struct node));   
  90.         E.free = E.size;   
  91.         E.size = expand_size;   
  92.            
  93.         /* init the node */  
  94.         node_init();   
  95.     }      
  96. }   
  97.   
  98. static void node_alloc(void *p, size_t sz, void (*finalizer)(void *))   
  99. {   
  100.     if (E.free >= E.size) {   
  101.         pool_expand();   
  102.     }
  103.     E.pool[E.free].mark = MARK_RESERVE;   
  104.     E.pool[E.free].level = NODE_NOW_LEVEL;   
  105.     E.pool[E.free].n.mem = p;   
  106.     E.pool[E.free].n.size = sz; // for mem_free   
  107.     E.pool[E.free].n.finalizer = finalizer;   
  108.            
  109.     E.free++;         
  110. }   
  111.   
  112.   
  113.   
  114. static void pool_init()   
  115. {   
  116.     E.pool = (struct node *)my_malloc(POOL_INITIAL_NUMBER * sizeof(struct node));   
  117.     E.free = 0;   
  118.     E.size = POOL_INITIAL_NUMBER;   
  119.        
  120.     /* init the node */  
  121.     node_init();   
  122. }   
  123.   
  124.   
  125.   
  126. void gc_init()   
  127. {   
  128.     E.pool = NULL;   
  129.     E.size = 0;   
  130.     E.free = -1;   
  131.     E.stack = init_stack();   
  132.        
  133.     pool_init();   
  134. }   
  135.   
  136. void gc_link(void *p, int level)   
  137. {   
  138.     int i;   
  139.        
  140.     for (i = 0; i < E.free; i++) {   
  141.         if (E.pool[i].n.mem == p) {   
  142.             E.pool[i].level = level;   
  143.             break;   
  144.         }   
  145.     }   
  146. }   
  147.   
  148. void gc_enter()   
  149. {   
  150.     push(E.stack, STACK_SECTION_TAG);   
  151. }   
  152.   
  153. /* accordind to the level of nodes, mark nodes. if in present stack section   
  154.  * of function, there are some nodes' life extend father function's life   
  155.  * which callthe present function, then push these nodes in stack section  
  156.  * of father's function.  
  157.  */  
  158.   
  159. void gc_leave()   
  160. {   
  161.     void *p;   
  162.     struct stack *stack_temp;   
  163.        
  164.     stack_temp = init_stack();   
  165.     while ((p = top(E.stack)) != STACK_SECTION_TAG) {   
  166.         int i;   
  167.            
  168.         /* whether mark for gc collect or not by searching for the node   
  169.             whose mem element equals p. */  
  170.         for (i = 0; i < E.free; i++) {   
  171.             if (E.pool[i].n.mem == p ) {   
  172.                 if (E.pool[i].level == NODE_NOW_LEVEL) {   
  173.                     E.pool[i].mark =  MARK_COLLECT;   
  174.                 } else if (E.pool[i].level == NODE_PRE_LEVEL) {   
  175.                     push(stack_temp, p);   
  176.                 }   
  177.                 break;   
  178.             }   
  179.         }   
  180.            
  181.         pop(E.stack);   
  182.     }   
  183.        
  184.     pop(E.stack); /* pop the STACK_SECTION_TAG */  
  185.        
  186.     while (! stack_empty(stack_temp)) {   
  187.         p = top(stack_temp);   
  188.         push(E.stack, p);   
  189.         pop(stack_temp);   
  190.     }   
  191.        
  192.     destory_stack(stack_temp);   
  193. }   
  194.   
  195. void gc_collect()   
  196. {   
  197.     int i;   
  198.        
  199.     for (i = 0; i < E.free; i++) {   
  200.         if (E.pool[i].mark == MARK_COLLECT) {   
  201.             void *p = E.pool[i].n.mem;   
  202.             int sz = E.pool[i].n.size;   
  203.             if (E.pool[i].n.finalizer != NULL) {   
  204.                 E.pool[i].n.finalizer(p);   
  205.             }   
  206.             my_free(p, sz); // for mem_free(p, size);   
  207.                
  208.             E.pool[i].mark = MARK_INITIAL;   
  209.         }   
  210.     }   
  211. }   
  212.   
  213. void *gc_malloc(size_t sz, void (* finalizer)(void *))   
  214. {   
  215.     void *result = my_malloc(sz);   
  216.     node_alloc(result, sz, finalizer);   
  217.     push(E.stack, result);   
  218.     return result;   
  219. }   
  220.   
  221. void *gc_realloc(void *p, size_t sz)   
  222. {   
  223.     void *result;   
  224.     assert(sz > 0);   
  225.        
  226.     if (p == NULL) {   
  227.         return gc_malloc(sz, NULL);   
  228.     }   
  229.        
  230.     /* find the node contain p */  
  231.     int i;   
  232.     int old_sz;   
  233.                    
  234.     for (i = 0; i < E.free; i++) {   
  235.         if (E.pool[i].n.mem == p) {   
  236.             old_sz = E.pool[i].n.size;   
  237.             break;   
  238.         }   
  239.     }   
  240.   
  241.     result = my_realloc(p, sz, old_sz);   
  242.     /* if new memory address is not change, just update size and return */  
  243.     if (result == p) {     
  244.         E.pool[i].n.size = sz;   
  245.         return result;   
  246.     } else {   
  247.         /* update size and mem */  
  248.         E.pool[i].n.size = sz;   
  249.         E.pool[i].n.mem = result;   
  250.            
  251.         /* update the stack infomation */  
  252.            
  253.         void *temp;   
  254.         struct stack *stack_temp = init_stack();   
  255.            
  256.         while ((! stack_empty(E.stack)) && ((temp = top(E.stack)) != p)) {   
  257.             push(stack_temp, temp);   
  258.             pop(E.stack);   
  259.         }   
  260.            
  261.         /* if the stack is not empty, pop the old address p and push   
  262.             the new address result */  
  263.            
  264.         if (! stack_empty(E.stack)) {   
  265.             pop(E.stack);   
  266.             push(E.stack, result);   
  267.         }   
  268.            
  269.         /* push the former data */  
  270.         while (! stack_empty(stack_temp)) {   
  271.             temp = top(stack_temp);   
  272.             push(E.stack, temp);   
  273.             pop(stack_temp);   
  274.         }   
  275.            
  276.         destory_stack(stack_temp);   
  277.     }   
  278.     return result;   
  279. }   
  280.   
  281. void gc_exit()   
  282. {   
  283.     /* the rest nodes (normally are root nodes) will free in this function */  
  284.     int i;   
  285.        
  286.     for (i = 0; i < E.free; i++) {   
  287.         if (E.pool[i].mark != MARK_INITIAL) {   
  288.             E.pool[i].mark = MARK_COLLECT;   
  289.         }   
  290.     }   
  291.        
  292.     gc_collect();   
  293.        
  294.     my_free(E.pool, E.size * sizeof(struct node));   
  295.        
  296.     destory_stack(E.stack);   
  297. }   
  298.   
  299. /* this remand the last paramater must be NULL */  
  300. void func_end(void *p, ...)   
  301. {   
  302.     va_list ap;   
  303.     void *temp = p;   
  304.     va_start(ap, p);   
  305.        
  306.     int i;   
  307.     while (temp != NULL) {   
  308.         for (i = 0; i < E.free; i++) {   
  309.             if (E.pool[i].n.mem == temp) {   
  310.                 E.pool[i].level = NODE_NOW_LEVEL;   
  311.                 break;   
  312.             }   
  313.         }   
  314.            
  315.         temp = va_arg(ap, void *);   
  316.     }   
  317.        
  318.     va_end(ap);   
  319. }   

这里给出测试代码:

Code:
  1. #include <stdio.h>   
  2. #include "gc.h"   
  3.   
  4. static void log_ptr(void *p)   
  5. {   
  6.     printf("free %p/n",p);   
  7. }   
  8.   
  9. int *foo1()   
  10. {   
  11.     printf("in function foo1:/n");   
  12.     int *p3 = gc_malloc(3, log_ptr);   
  13.     int *p4 = gc_malloc(6, log_ptr);   
  14.     int *p5 = gc_realloc(p4, 1024);   
  15.        
  16.     gc_link(p3, NODE_PRE_LEVEL);   
  17.     func_end(p3, NULL);   
  18.     return p3;   
  19. }   
  20.   
  21.   
  22. void foo()   
  23. {   
  24.     gc_enter();   
  25.     int *p1 = foo1();   
  26.     int *p2 = gc_malloc(4, log_ptr);   
  27.        
  28.     gc_link(p2, NODE_ROOT_LEVEL);   
  29.        
  30.     gc_leave();   
  31.        
  32.     printf("in foo:/n");   
  33.     gc_collect();   
  34. }   
  35.   
  36.   
  37. int main()   
  38. {   
  39.     gc_init();   
  40.        
  41.     gc_enter();   
  42.        
  43.     void *p = gc_malloc(5, log_ptr);   
  44.     foo();   
  45.        
  46.     gc_leave();   
  47.        
  48.     printf("in fuction main:/n");   
  49.     gc_collect();   
  50.     gc_exit();   
  51.        
  52.     return 0;   
  53. }   

运行结果:

实现C语言环境下的保守垃圾收集器 在计算机程序运行过程中,内存资源的使用并不是恒定不变的。动态内存分配允许程序在运行时申请和释放内存,但这同时也带来了内存管理的复杂性。垃圾收集(Garbage Collection, GC)就是用来自动识别和回收程序中不再使用的对象,以避免内存泄漏和其他内存相关问题的一种机制。垃圾指的是程序中已经分配出去的内存,但其后再也无法被程序访问到的对象所占用的空间。垃圾的识别通常依赖于两种策略:引用计数和可达性分析。 阅读详情

相关推荐

mark-sweep:C语言中一个简单的标记清除垃圾收集器

这是示例代码。

写一个基于C语言的保守垃圾回收器

最近在实现链表的时候总是忘记释放内存,所以心想能不能在C语言的基础上实现一个像Java那样的垃圾回收机制来帮助程序员更好地管理内存。虽然技术有限,这个垃圾回收器不能够像JVM那样强大,但是没关系,许多计算机界的大佬做的项目最初并不一定用到了多么高大上的技术,重点在于它们做出了第一个这样的东西。所以,我们只需要设计出一个雏形,日后加以改进就行了。

CairBin的博客 785

修复zookeeper未授权访问漏洞

【代码】修复zookeeper未授权访问漏洞。

qq_28392947的博客 4067

一个简易的c垃圾收集器

houapple的记忆屋 1986

SBM与超效率SBM模型实战:从原始面板数据到MATLAB高效实现

本文详细介绍了SBM模型与超效率SBM模型的核心原理,并提供了从原始面板数据预处理到MATLAB高效实现的完整实战指南。通过具体代码解析,帮助研究者掌握如何利用MATLAB进行数据标准化、模型构建、效率求解及结果可视化,从而精准评估决策单元的相对效率,尤其适用于在高效单元中进一步精细排名的场景。

weixin_29100399的博客 477

三维旋转详细解读(Rodrigues‘ Roatation Formula 罗德里格旋转公式)

三维旋转引言三维旋转1)欧拉角2)轴角式旋转分解1)V||的旋转2)V⊥的旋转3)V的整体旋转 引言 前面我们了解了 复数在二维旋转中的作用与联系 而四元数与三维旋转之间的关系与复数对二维旋转有很多类似的地方,下面我们就先来详细了解一下三维旋转的过程。 三维旋转 首先讨论一下三维旋转,我们了解到常用的三维旋转有两种方式: 1)欧拉角 即按照一定的顺序,分别对X, Y, Z三个轴进行旋转 θ 角。绕各旋转轴的旋转矩阵为: 然后任意的三维旋转可以分解成上述三种旋转方式的组合。(注意:三个旋转的顺序是非常重要的

晓晨的博客 1万+

编写你的第一个垃圾收集器

每当我倍感压力以及有很多事情要做的时候,我总是有这样一种反常的反应,那就是希望做一些其他的事情来摆脱这种状况。通常情况下,这些事情都是些我能够编写并实现的独立的小程序。 一天早上,我几乎要被一堆事情给整疯了——我得看一本书、处理一些工作上的事情、还要准备一场Strange Loop的演讲,然后这时我突然想到:“我该写一个垃圾收集器了”。 是的,我知道那一刻让我看上去有多疯狂。不过我

chivalry 1152

保姆级教程:从OrthoFinder到CAFE5,手把手搞定基因家族收缩扩张分析(附完整代码与避坑指南)

本文提供从OrthoFinder到CAFE5的基因家族收缩扩张分析全流程教程,涵盖数据预处理、系统发育树准备、CAFE5运行与参数优化等关键步骤。通过详细代码示例和避坑指南,帮助研究者高效完成基因家族进化分析,特别适合生物信息学初学者。

dianshu1593的博客 390

GC垃圾回收、RAII实现概述 自己动手写垃圾回收器 C语言垃圾回收器 自己写GC

课本是: 日本人写的 垃圾回收算法与思想, 可能要配套看一些论文, GC 是因为 6.s081 vm 的用法里提了一下, DUNE 应用里面也提到了 user level 应用 s 模式指令来完成 GC 的一个例子. 常见 GC 总结 算法 堆利用 复杂度 默认下 STW 可改进缺点 改进 其他优缺点 保守与精确 Mark

锐龙处理器 1324

【YOLO11改进 - C3k2融合】C3k2融合动态蛇形卷积(Dynamic Snake Convolution)用于管状结构分割任务

【YOLO11改进 - C3k2融合】C3k2融合动态蛇形卷积(Dynamic Snake Convolution)用于管状结构分割任务

专注于图像领域,主要研究内容包括计算机视觉和深度学习,特别是在图像分类、目标检测和图像生成等方面有深入的研究和实践经验。 516

022、Conv-BN-SiLU 基础卷积块:构造函数参数计算,前向传播的 PyTorch 逐行实现

本文详细解析了Conv-BN-SiLU卷积块的实现细节与注意事项。作者从调试经历出发,指出bias参数冗余会导致数值不稳定,强调卷积层应设置bias=False。文章对比了SiLU与ReLU的特性差异,逐行分析了构造函数参数计算(包括自动填充、分组卷积等)和前向传播过程,特别讲解了BN层与SiLU激活的数值特性。最后分享了三个实践中的常见问题:BN的momentum设置、SiLU输出范围的影响,以及分组卷积的通道对齐要求,并提供了卷积与BN融合的推理优化技巧。全文聚焦实际工程实现中的关键细节,具有较强实操指

ai技术增长的博客 217

十六-垃圾回收相关概念

16.1 System.gc()的理解 默认情况下,通过System.gc()或Runtime.getRuntime().gc()的调用,会显示触发Full GC,同时堆老年代和新生代进行回收,尝试释放被丢弃对象占用的内存 然而System.gc()调用附带一个免责声明,无法保证堆垃圾收集器的调用 JVM实现者可以通过System.gc()调用来决定JVM的GC的行为。一般情况下,垃圾回收应该使自动进行的,无须手动触发,否则过于麻烦。 public class SystemGCTest { pu

u014215131的博客 220

基于模型上下文协议(MCP)的可插拔式临床AI工具链Clinical DS研究(下)

本研究深入探讨了医疗AI在临床落地中的核心矛盾,即如何从“模型能答”迈向“系统可信、可用、可追溯”。为解决此矛盾,我们创新性地提出并详细设计实现了一套基于模型上下文协议(MCP)的**“可插拔式临床AI工具链”**架构。通过将复杂的医疗AI系统解构为Host、MCP Server和标准协议三层,并将各类能力(临床决策、影像分析、合规审计)封装为标准的、可独立演进的Server,我们成功地构建了一个模块化、高内聚、低耦合的系统。

AllenLV的博客 1380

垃圾收集器

每当我倍感压力以及有很多事情要做的时候,我总是有这样一种反常的反应,那就是希望做一些其他的事情来摆脱这种状况。通常情况下,这些事情都是些我能够编写并实现的独立的小程序。 一天早上,我几乎要被一堆事情给整疯了——我得看一本书、处理一些工作上的事情、还要准备一场Strange Loop的演讲,然后这时我突然想到:“我该写一个垃圾收集器了”。 是的,我知道那一刻让我看上去有多疯狂。不过我

suilingxi的专栏 475

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

JVM几种常见的垃圾收集器总结

前言 在介绍垃圾收集器之前,首先介绍以下这几个概念 1. Stop-the-world 它是指 JVM 由于要执行 GC 而停止了应用程序的执行,并且这种情形会在任何一种 GC 算法中发生。当 Stop-the-world 发生时,除了 GC 的线程以外,其他的线程均处于等待的状态,直到 GC 任务完成。 实际上,很多 GC 优化都是通过减少 Stop-the-world 的时间来提高程序的性能。...

To be a great coder 9446

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

JVM之垃圾收集器

JVM垃圾收集器是垃圾回收算法(标记-清除算法、复制算法、标记-整理算法)的具体实现,不同JVM所提供的垃圾收集器可能会有很大差别。Java垃圾回收器为应用程序提供内存的自动分配、自动回收功能。

积跬步,至千里。 819

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

一个简单开发的垃圾收集器工作原理详解

一个简单开发的垃圾收集器工作原理详解 一.工作原理       最近在实现一个阉割版的函数式语言(编译器已完成,虚拟机在憋的过程中,之后会发帖),希望内存管理的部分由虚拟机来完成,而不是由客户自己折腾,这样显然可以降低客户使用这门语言的难度,比如不需要担心内存泄漏,减少内存运用不当的bug,这里客户只管放心地一直申请内存就行,不再需要手工释放内存(如果让客户选择是否自己释放都行,会

chenglinhust的专栏 2233

实战指南:如何将mark-sweep垃圾收集器集成到你的C项目

你是否正在为C语言项目中的内存管理问题而烦恼?想要一个简单高效的**垃圾收集器**来解放双手吗?今天我将为你详细介绍如何将**mark-sweep垃圾收集器**集成到你的C项目中,让你彻底告别内存泄漏的困扰!🎯 ## 什么是mark-sweep垃圾收集器? **mark-sweep垃圾收集器**是一种经典的垃圾回收算法,它通过两个阶段工作:标记(mark)和清除(sweep)。这种算法特别适

gitblog_00948的博客 605

怎么查看服务器默认的垃圾收集器是哪个?生产上如何配置垃圾收集器的?谈谈你对垃圾收集器的理解?

怎么查看服务器默认的垃圾收集器: E:\ideaProjects\suanfa>java -XX:+PrintCommandLineFlags -version -XX:InitialHeapSize=132345856 -XX:MaxHeapSize=2117533696 -XX:+PrintCommandLineFlags -XX:+UseCompressedOops -XX:-UseL...

sakuragio的博客 1831

HotSpot的经典垃圾收集器

HotSpot的经典垃圾收集器。

Stay Hungry,Stay Foolish 1757

给 C 实现一个垃圾收集器

原文转自云风的Blog:http://blog.codingnow.com/2008/06/gc_for_c.html

达闻东的专栏 1120

7 怎么查看服务器默认垃圾收集器是哪个?生产是如何配置垃圾收集器?谈谈你对垃圾收集器的理解?

怎么查看服务器默认垃圾收集器是哪个? Java -XX:+PrintCommandLineFlags Java 的 GC 回收的类型主要有: UseSerialGC,UseParallelGC,UseConcMarkSweepGC,UseParNewGC,UseParallelOldGC,UseG1GC Java 8 以后基本不使用 Serial Old 垃圾收集器 参数说明...

weixin_39456915的博客 408
上一篇: windows“运行”自定义“命令”的实现
下一篇: 在 C++ 中实现一个轻量的标记清除 gc 系统
pi9nc
博客等级 码龄18年 3512粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值