Profiling means monitoring code at RunTime to collect information about what it spends its time doing. The goal is to identify computationally intensive parts worthy of Optimisation -- either manually by a programmer tweaking the SourceCode, or automatically during CompileTime.
Automatic Optimisation generally yields much lower gains, but manual Optimisation is expensive. The two methods are therefor generally complementary; you will usually want to make initial Optimisations manually, yielding greater speedups before diminishing returns render further effort inefficient, and then squeeze out a little more performance yet by automatic means.
If a traditional Compiler is used, Profiling information is generally saved to disk, either as a summary (requires more RAM) or as a log (requires more diskspace), and then postprocessed for use by the Compiler. GCC uses the -pg argument to build BinaryExecutables instrumented with profiling code and gprof(1) to display the resulting data. The JVM has profiling infrastructure already built into it, so normally compiled Java classes can always be profiled. There is a standard interface to the profiling and debugging features and several user-level interfaces, including fancy GUI applications.