Session Boundaries#
One of the main purposes of an environment is to indicate when your program will start to use Gurobi, and when it is done. When Gurobi is running on your own machine, creating an environment will obtain a license, and disposing of the environment will release that license. When you are a client of a Gurobi Compute Server, starting an environment will start a job on the server (or place the job in the queue if the server is fully occupied). Disposing of the environment will end that job, allowing the next job in the queue to start. On Gurobi Instant Cloud, creating an environment will launch a cloud instance (if it hasn’t been launched already). Disposing of the environment will end that session, which may result in the cloud instance being shut down (depending on the policy you’ve set in your Instant Cloud configuration).
If your program repeatedly creates, solves, and destroys optimization models, we strongly recommend that you do so within a single Gurobi environment. Creating a Gurobi environment incurs overhead, ranging anywhere from a quick local license check all the way to spinning up a machine on the cloud. By reusing a single environment, you avoid paying this overhead multiple times.
We also recommend that you dispose of your environment as soon as your program is done using Gurobi. Doing so releases all resources associated with that session, which in many cases can make those resources available to other users. You should pay particular attention to this topic when using programming languages that perform garbage-collection. While it is true that environments will be disposed of eventually by automated garbage-collection, that will often happen much earlier if you dispose of them explicitly.
The actual steps for disposing of an environment will depend on the API you are using:
Call GRBfreemodel() for each model, then
call GRBfreeenv() for the Gurobi environment.
For example:
GRBenv *env = NULL;
GRBmodel *model = NULL;
int error = 0;
/* Create environment */
error = GRBloadenv(&env, "example.log");;
if (error) goto QUIT;
/* Create an empty model */
error = GRBnewmodel(env, &model, "example", 0, NULL, NULL, NULL, NULL, NULL);
if (error) goto QUIT;
/* Create and add variables, constraints, objective; solve model */
/* ... */
QUIT:
/* Clean up model and environment */
GRBfreemodel(model);
GRBfreeenv(env);
The destructors of GRBEnv and GRBModel will be invoked when
required and will release the resources used by these objects.
For example:
/* Create environment */
GRBEnv env = GRBEnv();
/* Create model */
GRBModel model = GRBModel(env);
/* Create and add variables, constraints, objective; solve model */
/* ... */
Methods GRBModel.Dispose() and
GRBEnv.Dispose() are invoked
automatically when these objects are used in a using statement
or using declaration.
For example:
// Create environment
using GRBEnv env = new GRBEnv("example.log");
// Create empty model
using GRBModel model = new GRBModel(env);
// Create and add variables, constraints, objective; solve model
// ...
' Create environment
Using env As New GRBEnv("example.log")
' Create empty model
Using model As New GRBModel(env)
' Create and add variables, constraints, objective; solve model
' ...
End Using
End Using
Call GRBModel.dispose() on all
GRBModel objects, then call
GRBEnv.dispose() on the GRBEnv
object. For example:
GRBEnv env = null;
GRBModel model = null;
try {
// Create environment
env = new GRBEnv("example.log");
// Create empty model
model = new GRBModel(env);
// Create and add variables, constraints, objective; solve model
// ...
} finally {
// Clean up model and environment
if (model != null) {
model.dispose();
}
if (env != null) {
env.dispose();
}
}
The model and environment will be closed automatically at the end of the context. For example:
with gp.Env() as env:
with gp.Model(env=env) as model:
# construct, solve, and post-process `model`
# ...
Refer to Env class documentation for more information.
A typical use pattern is also shown in the example
mip1_remote.py.
Note that the boundaries established by an environment are for a single thread. Gurobi environments are not thread-safe, so you can’t have more than one thread of control within a single environment. You can however have a single program that launches multiple threads, each with its own environment.