检查Groovy版本Gradle正在使用(Checking Groovy version Gradle is using)
我正在运行gradle,之前一直在运行groovy 1.76。 我现在更新到我的本地机器groovy(groovy_home指向groovy 2.1.2等)。
$ groovy -version Groovy Version: 2.1.2 JVM: 1.7.0_17 Vendor: Oracle Corporation OS: Linux
然而,当我运行gradle命令(gradle test,classes等)时,我认为它不是针对groovy 2.1.2构建的,而实际上仍然是针对1.76构建的。 (我相信这个的原因是,当我执行这些类时,我不断收到此错误升级Groovy 1.7 - 2.1不兼容性 ,这与1.76后发生的更改有关)
有没有一种方法可以确认我的Gradle安装的哪个版本的Groovy正在构建?
另外,任何人都可以确认我应该配置Groovy的Groovy版本吗?
I am running gradle and have previously been running groovy 1.76. I have now updated to groovy on my local machine (groovy_home points to groovy 2.1.2 etc).
$ groovy -version Groovy Version: 2.1.2 JVM: 1.7.0_17 Vendor: Oracle Corporation OS: Linux
However, when I am running gradle commands (gradle test, classes, etc) I believe it is not building against groovy 2.1.2 but is actually still building against 1.76. (The reason I believe this, is that when I execute the classes I keep getting this error Upgrading Groovy 1.7 - 2.1 Incompatability, which is related to changes made post 1.76)
Is there a way to confirm which version of groovy my gradle install is building against?
Also, can anyone confirm where I should be configuring the groovy version for gradle?
原文:https://stackoverflow.com/questions/16527384
最满意答案
首先,您没有使用未使用的
vector
进行任何测试。 编译器是聪明的,并且-O2
gcc
和clang
都将上面的代码编译为空的main()
(除了单个xor eax, eax
以设置返回值。请参阅此处的程序集。此外,大多数vector
的默认构造函数实现(包括gcc
和clang
)甚至不会分配任何东西 - 它会等到第一个元素被添加之后再进行昂贵的分配步骤。要获得更具体的结果,请分配一个BIG向量(以便将其与噪声区分开)并将其传递给另一个转换单元中的方法(或在单独的.cpp文件中定义),如下所示:
#include <vector> void sink(std::vector<int>& v); int main() { std::vector<int> v(12345678); sink(v); }
现在,当您检查程序集时,您会发现它实际上正在执行某些操作 。
因此,Valgrind报告的~72,000字节与您的
std::vector<int> v
无关,您可能会看到完全为空的main的相同数字。问题和引用文献的想法仍然与该问题不同,我将在下面回答。
程序退出时, 所有内存通常都会释放回操作系统,操作系统会强制执行此操作,而不是标准库。 操作系统只是清理进程使用的所有资源,包括非共享内存分配。 当Valgrind提到“在退出时使用”时,它正在讨论此操作系统清理之前,因为这是您想要知道的,看看您是否忘记释放任何东西。
您不需要任何单独的过程。 它只是意味着Valgrind可以跟踪
malloc
和free
调用以及其他一些标准分配例程,但是标准库可能会在需要malloc
最初调用malloc
(或者operator new
或某些等价物)的那些上面使用另一层,但是当内存由进程取消分配,它将内部保存在某个列表中,而不是调用相应的取消分配例程(例如free
)。 在后续分配中,它将使用其列表中的内容而不是返回标准方法(如果列表已用尽,则必须调用标准例程)。 由于旧版本的C ++中std::allocator
定义有些无用,因此没有大量使用,但它在更新的标准中有所改变。 最大的好处是(a)为容器使用线程局部的固定大小分配,因为所有包含的对象大小相同,并且(b)允许分配器在容器被销毁时释放一个操作中的所有内容而不是逐个元素释放。你引用的文档有点令人困惑,因为它谈到(不)重新调整内存到操作系统 - 但它应该说“重新调整到标准分配例程”。 Valgrind不需要将内存返回到操作系统以将其视为已释放 - 它会挂钩所有标准例程并知道何时释放该级别。 标准例程本身大量“缓存”分配的内存,如上所述(这是常见的,不像分配器例程缓存,这是不常见的),因此如果Valgrind需要将内存返回到操作系统,那么报告“退出时分配的内存”将毫无用处。
How does the C++ library implementation achieve that?
It doesn't. The valgrind information is outdated, I don't think any modern C++ implementations do that.
Does it keep around a separate process in the background that handles all allocation requests from its standard templates, so that when the program exits (a.out here), the memory is not immediately given back to the OS?
No, you've misunderstood. The valgrind docs aren't talking about keeping memory around that outlives the process. It's just talking about keeping memory pools within the process so that memory allocated and then deallocated by the process is kept in a pool and reused (by the same process!) later, instead of calling
free
immediately. But nobody does that forstd::allocator
nowadays, becausestd::allocator
needs to be general purpose and perform reasonably well in all scenarios, and a goodmalloc
implementation should meet those needs anyway. It's also fairly easy for users to override the default system malloc with an alternative like tcmalloc or jemalloc, so ifstd::allocator
just forwards to malloc then it gets all the benefits of that replacement malloc.If so, when will it give back, and how can I check the process indeed exists? If not, what is the "magic" behind the scene?
All memory in a process is returned to the OS when the process exits. There is no magic.
But the allocation you're seeing has nothing to do with this anyway.
There is 71 KB allocated. Why this number?
The 72kb you're seeing is allocated by the C++ runtime for its "emergency exception-handling pool". This pool is used to be able to allocate exception objects (such as
bad_alloc
exceptions) even whenmalloc
can no longer allocate anything. We pre-allocate at startup, so ifmalloc
runs out of memory we can still throwbad_alloc
exceptions.The specific number comes from this code:
// Allocate the arena - we could add a GLIBCXX_EH_ARENA_SIZE environment // to make this tunable. arena_size = (EMERGENCY_OBJ_SIZE * EMERGENCY_OBJ_COUNT + EMERGENCY_OBJ_COUNT * sizeof (__cxa_dependent_exception)); arena = (char *)malloc (arena_size);
Newer versions of
valgrind
know about this emergency EH pool and call a special function to free it right before the process exits, so that you don't seein use at exit: 72,704 bytes in 1 blocks
. This was done because too many people fail to understand that memory still in use (and still reachable) is not a leak, and people kept complaining about it. So now valgrind frees it, just to stop people complaining. When not running under valgrind the pool doesn't get freed, because doing so is unnecessary (the OS will reclaim it when the process exits anyway).
相关问答
更多-
TCP/IP模型是一个________。[2023-05-19]
a -
下列中不属于面向对象的编程语言的是?[2022-05-30]
a -
首先,您没有使用未使用的vector进行任何测试。 编译器是聪明的,并且-O2 gcc和clang都将上面的代码编译为空的main() (除了单个xor eax, eax以设置返回值。请参阅此处的程序集。此外,大多数vector的默认构造函数实现(包括gcc和clang )甚至不会分配任何东西 - 它会等到第一个元素被添加之后再进行昂贵的分配步骤。 要获得更具体的结果,请分配一个BIG向量(以便将其与噪声区分开)并将其传递给另一个转换单元中的方法(或在单独的.cpp文件中定义),如下所示: #include ...
-
程序退出后,C / C ++中的对象是否被垃圾收集?(Do objects in C/C++ get garbage collected after the program exits?)[2022-03-22]
是的,当您的程序退出时,操作系统将自动释放您没有释放的任何内存。 这意味着在任何时候调用exit()通常都是安全的,尽管您需要注意其他未自动释放的资源,例如Windows上的全局原子和命名管道等。 Yes, any memory you don't free will be automatically freed by the operating system when your program exits. This means it's generally safe to call exit() at ... -
为什么分配内存?(Why allocate memory? (C++))[2022-01-22]
为什么分配内存是必要的? 因此,您将内存标记为您的内存。 没有其他人可以使用它。 它还验证实际上有可用内存。 如果你的系统只有1000字节的内存,那么选择字节1500来存储一些数据是一个坏主意。 如果我们使用内存而不分配它会发生什么? 没人知道。 您写的地址可能不存在。 可能已经开始使用其他进程,因此您将覆盖其数据。 记忆可以得到保护; 例如,在前一种情况下,操作系统可能会注意到您正在访问另一个进程已声明的内存,并阻止您。 您可能拥有该内存区域,但程序的另一部分由于某种原因正在使用它,并且您已经覆盖了自己的 ... -
我的懒惰...... 这是80 * 60 * 5 (Hz x秒x分钟)周期的结果: Process only:: mean: 0.00356445 in seconds Alloc Dealloc:: mean: 0.0743379 in seconds 这是代码和冗余输出: 分配 - 每次解除分配 class AllocEvery { public: int doSomething() { double pi, gold, ogh; std::strin ...
-
只要您使用内存分配运行时链接到共享的MSVC库,这就可以工作。 然后EXE和DLL共享同一个堆。 如果您破坏了此依赖关系,则将不再共享堆,并且删除不同堆中的对象将破坏应用程序。 That works as long as you link to shared MSVC libraries with the memory allocation runtime. Then EXE and DLL share the same heap. If you break this dependency, the hea ...
-
我强烈建议进行分配的模块也负责进行解除分配。 从而: int *ptr = module1->getIntData(); ... module1->freeIntData(ptr); 这允许不同的模块毫无困难地使用不同的分配器(malloc / free,new / delete,slab allocator等)。 在Posix系统上,进程中只能有一个malloc (和free )实现,所以如果getIntData的定义是“返回一个必须free释放的指针”,那么你getIntData了。 另一方面,我认为 ...
-
这在很大程度上取决于您的编译器和openmp库实现。 我用gcc -fopenmp版本4.4.6(GCC)和libgomp 1.0.0尝试了你的代码,我也得到了尚未解除分配的堆块。 据我所知, libgomp并没有在执行结束时杀死它的衍生线程并使内核清理干净。 ==85122== HEAP SUMMARY: ==85122== in use at exit: 2,072 bytes in 4 blocks ==85122== total heap usage: 203 allocs, 199 f ...
-
你应该使用new char而不是new char*来分配,因为new char*会分配那么多的指针。 这导致您从*frameBuffer =删除*意味着不会更改调用者的frameBuffer参数。 将行更改为 *framebuffer = new char[sizeof(Pixel) * width *height]; You should allocate using new char not new char* as new char* will allocate that many pointers ...