Project: MongoDB (App Definition and Development / Database)
File: quickstart.md

Note: this Quickstart uses Bazel as the official build system for TCMalloc, which is supported on Linux, and compatible with most major compilers. The TCMalloc source code assumes you are using Bazel and contains `BUILD.bazel` files for that purpose. This document is designed to allow you to get TCMalloc set up as your custom allocator within a C++ development environment. We recommend that each person starting development using TCMalloc at least run through this quick tutorial. Running the code within this tutorial requires: A compatible platform (E.g. Linux). Consult the for more information. A compatible C++ compiler supporting at least C++17*. Most major compilers are supported. for interacting with the Abseil source code repository, which is contained on . To install Git, consult the guide on GitHub. Although you are free to use your own build system, most of the documentation within this guide will assume you are using , version 4.0 or newer. To download and install Bazel (and any of its dependencies), consult the . You can obtain the TCMalloc code from its repository on GitHub: ``` $ cd ~ $ mkdir Source; cd Source $ git clone https://github.com/google/tcmalloc.git Cloning into 'tcmalloc'... remote: Total 1935 (delta 1083), reused 1935 (delta 1083) Receiving objects: 100% (1935/1935), 1.06 MiB | 0 bytes/s, done. Resolving deltas: 100% (1083/1083), done. $ ``` Git will create the repository within a directory named `tcmalloc`. Navigate into this directory and run all tests: ``` $ cd tcmalloc $ bazel test //tcmalloc/... INFO: Analyzed 112 targets (12 packages loaded, 606 targets configured). ... INFO: Build completed successfully, 827 total actions $ ``` Congratulations! You've installed TCMalloc Once you've verified you have TCMalloc installed correctly, you can compile and run the sample binary to see how TCMalloc is linked into a sample binary. This tiny project features proper configuration and a simple `hello_main` to demonstrate how TCMalloc works. First, build the `tcmalloc/testing:hello_main` target: ``` tcmalloc$ bazel build tcmalloc/testing:hello_main Extracting Bazel installation... Starting local Bazel server and connecting to it... INFO: Analyzed target //tcmalloc/testing:hello_main (31 packages loaded ... ... INFO: Build completed successfully, 102 total actions PASSED in 0.1s tcmalloc$ ``` Now, run the compiled program: ``` tcmalloc$ bazel run tcmalloc/testing:hello_main ... INFO: Found 1 target... ... INFO: Build completed successfully, 1 total action Current heap size = 73728 bytes hello world! new'd 1073741824 bytes at 0x14ea40000000 Current heap size = 1073816576 bytes malloc'd 1073741824 bytes at 0x14eac0000000 Current heap size = 2147558400 bytes $ ``` You can inspect this code within Happy Coding! Now that you've obtained the TCMalloc code and verified that you can build, test, and run it, you're ready to use it within your own project. First, create (or select) a source code directory for your

This directory should generally not be the `tcmalloc` directory itself; instead, you will link into that repository from your own source directory. ``` $ cd ~/Source $ mkdir TestProject; cd TestProject ``` Bazel allows you to link other Bazel projects using `WORKSPACE` files in the root of your development directories. To add a link to your local TCMalloc repository within your new project, add the following into a `WORKSPACE` file: ``` local_repository( name = "comgoogletcmalloc", path = "/PATHTOSOURCE/Source/tcmalloc", ) ``` The "name" in the `WORKSPACE` file identifies the name you will use in Bazel `BUILD` files to refer to the linked repository (in this case "comgoogletcmalloc"). Note that your path to the TCMalloc source code must be an absolute path. TCMalloc requires which you will also need to provide as a `local_repository`, or link to a specific commit (we always recommend the latest commit) using an `http_archive` declaration in the `WORKSPACE` file: <pre> http_archive( name = "comgoogleabsl", urls = ["https://github.com/abseil/abseil-cpp/archive/<i>commit_value</i>.zip"], stripprefix = "abseil-cpp-<i>commitvalue</i>", sha256 = "<i>sha256ofcommit_value</i>", ) </pre> Within your `TestProject` create an `examples` directory: ``` $ cd TestProject; mkdir examples; cd examples ``` Now, create a `hello_world.cc` C++ file within your `examples` directory: ``` int main() { std::cout << "Standard Alignment: " << alignof(std::maxalignt) << '\n'; double ptr = (double) malloc(sizeof(double)); std::cout << "Double Alignment: " << alignof(*ptr) << '\n'; char ptr2 = (char) malloc(1); std::cout << "Char Alignment: " << alignof(*ptr2) << '\n'; void *ptr3; std::cout << "Sizeof void*: " << sizeof(ptr3) << '\n'; return 0; } ``` Now, create a `BUILD` file within your `examples` directory like the following: ``` cc_binary( name = "hello_world", srcs = ["hello_world.cc"], malloc = "@comgoogletcmalloc//tcmalloc", ) ``` NOTE: For more information on how to create Bazel BUILD files, consult the . We declare TCMalloc as our own custom allocation framework using the `malloc` keyword and set this to the library name (`//tcmalloc`) within our `WORKSPACE` file (`@comgoogletcmalloc`). Build our target ("hello_world") and run it: ``` $ cd ~/Source/TestProject Source/TestProject$ bazel build //examples:hello_world --cxxopt='-std=c++17' INFO: Analysed target //examples:hello_world (12 packages loaded). INFO: Found 1 target... Target //examples:hello_world up-to-date: bazel-bin/examples/hello_world INFO: Elapsed time: 0.180s, Critical Path: 0.00s INFO: Build completed successfully, 1 total action Source/TestProject$ bazel run //examples:hello_world INFO: Running command line: bazel-bin/examples/hello_world Standard Alignment: 16 Double Alignment: 8 Char Alignment: 1 Sizeof void*: 8 Source/TestProject$ ``` Note that we passed `--cxxopt='std=c++17'` to build using C++17. Instead of passing this flag you can add this line to your root `.bazelrc` file: ``` build --cxxopt='-std=c++17' ``` Congratulations! You've created your first binary using TCMalloc. Read our , if you haven't already. The overview covers memory allocation concepts and best practices for using TCMalloc. Read through the TCMalloc for information on the behavior of `malloc()`, `::operator new`, and other allocation/deallocation routines in TCMalloc. Consult the TCMalloc C++ `malloc_extension.h` header file, which contains information on TCMalloc's supported extensions. Read our , if you intend to submit code to our repository.